1 use super::*;
2 use proc_macro2::{Span, TokenStream};
3 use punctuated::Punctuated;
4 #[cfg(feature = "extra-traits")]
5 use std::hash::{Hash, Hasher};
6 #[cfg(all(feature = "parsing", feature = "full"))]
7 use std::mem;
8 #[cfg(feature = "extra-traits")]
9 use tt::TokenStreamHelper;
10
11 ast_enum_of_structs! {
12 /// A Rust expression.
13 ///
14 /// *This type is available if Syn is built with the `"derive"` or `"full"`
15 /// feature.*
16 ///
17 /// # Syntax tree enums
18 ///
19 /// This type is a syntax tree enum. In Syn this and other syntax tree enums
20 /// are designed to be traversed using the following rebinding idiom.
21 ///
22 /// ```edition2018
23 /// # use syn::Expr;
24 /// #
25 /// # fn example(expr: Expr) {
26 /// # const IGNORE: &str = stringify! {
27 /// let expr: Expr = /* ... */;
28 /// # };
29 /// match expr {
30 /// Expr::MethodCall(expr) => {
31 /// /* ... */
32 /// }
33 /// Expr::Cast(expr) => {
34 /// /* ... */
35 /// }
36 /// Expr::If(expr) => {
37 /// /* ... */
38 /// }
39 ///
40 /// /* ... */
41 /// # _ => {}
42 /// # }
43 /// # }
44 /// ```
45 ///
46 /// We begin with a variable `expr` of type `Expr` that has no fields
47 /// (because it is an enum), and by matching on it and rebinding a variable
48 /// with the same name `expr` we effectively imbue our variable with all of
49 /// the data fields provided by the variant that it turned out to be. So for
50 /// example above if we ended up in the `MethodCall` case then we get to use
51 /// `expr.receiver`, `expr.args` etc; if we ended up in the `If` case we get
52 /// to use `expr.cond`, `expr.then_branch`, `expr.else_branch`.
53 ///
54 /// This approach avoids repeating the variant names twice on every line.
55 ///
56 /// ```edition2018
57 /// # use syn::{Expr, ExprMethodCall};
58 /// #
59 /// # fn example(expr: Expr) {
60 /// // Repetitive; recommend not doing this.
61 /// match expr {
62 /// Expr::MethodCall(ExprMethodCall { method, args, .. }) => {
63 /// # }
64 /// # _ => {}
65 /// # }
66 /// # }
67 /// ```
68 ///
69 /// In general, the name to which a syntax tree enum variant is bound should
70 /// be a suitable name for the complete syntax tree enum type.
71 ///
72 /// ```edition2018
73 /// # use syn::{Expr, ExprField};
74 /// #
75 /// # fn example(discriminant: ExprField) {
76 /// // Binding is called `base` which is the name I would use if I were
77 /// // assigning `*discriminant.base` without an `if let`.
78 /// if let Expr::Tuple(base) = *discriminant.base {
79 /// # }
80 /// # }
81 /// ```
82 ///
83 /// A sign that you may not be choosing the right variable names is if you
84 /// see names getting repeated in your code, like accessing
85 /// `receiver.receiver` or `pat.pat` or `cond.cond`.
86 pub enum Expr {
87 /// A box expression: `box f`.
88 ///
89 /// *This type is available if Syn is built with the `"full"` feature.*
90 pub Box(ExprBox #full {
91 pub attrs: Vec<Attribute>,
92 pub box_token: Token![box],
93 pub expr: Box<Expr>,
94 }),
95
96 /// A placement expression: `place <- value`.
97 ///
98 /// *This type is available if Syn is built with the `"full"` feature.*
99 pub InPlace(ExprInPlace #full {
100 pub attrs: Vec<Attribute>,
101 pub place: Box<Expr>,
102 pub arrow_token: Token![<-],
103 pub value: Box<Expr>,
104 }),
105
106 /// A slice literal expression: `[a, b, c, d]`.
107 ///
108 /// *This type is available if Syn is built with the `"full"` feature.*
109 pub Array(ExprArray #full {
110 pub attrs: Vec<Attribute>,
111 pub bracket_token: token::Bracket,
112 pub elems: Punctuated<Expr, Token![,]>,
113 }),
114
115 /// A function call expression: `invoke(a, b)`.
116 ///
117 /// *This type is available if Syn is built with the `"derive"` or
118 /// `"full"` feature.*
119 pub Call(ExprCall {
120 pub attrs: Vec<Attribute>,
121 pub func: Box<Expr>,
122 pub paren_token: token::Paren,
123 pub args: Punctuated<Expr, Token![,]>,
124 }),
125
126 /// A method call expression: `x.foo::<T>(a, b)`.
127 ///
128 /// *This type is available if Syn is built with the `"full"` feature.*
129 pub MethodCall(ExprMethodCall #full {
130 pub attrs: Vec<Attribute>,
131 pub receiver: Box<Expr>,
132 pub dot_token: Token![.],
133 pub method: Ident,
134 pub turbofish: Option<MethodTurbofish>,
135 pub paren_token: token::Paren,
136 pub args: Punctuated<Expr, Token![,]>,
137 }),
138
139 /// A tuple expression: `(a, b, c, d)`.
140 ///
141 /// *This type is available if Syn is built with the `"full"` feature.*
142 pub Tuple(ExprTuple #full {
143 pub attrs: Vec<Attribute>,
144 pub paren_token: token::Paren,
145 pub elems: Punctuated<Expr, Token![,]>,
146 }),
147
148 /// A binary operation: `a + b`, `a * b`.
149 ///
150 /// *This type is available if Syn is built with the `"derive"` or
151 /// `"full"` feature.*
152 pub Binary(ExprBinary {
153 pub attrs: Vec<Attribute>,
154 pub left: Box<Expr>,
155 pub op: BinOp,
156 pub right: Box<Expr>,
157 }),
158
159 /// A unary operation: `!x`, `*x`.
160 ///
161 /// *This type is available if Syn is built with the `"derive"` or
162 /// `"full"` feature.*
163 pub Unary(ExprUnary {
164 pub attrs: Vec<Attribute>,
165 pub op: UnOp,
166 pub expr: Box<Expr>,
167 }),
168
169 /// A literal in place of an expression: `1`, `"foo"`.
170 ///
171 /// *This type is available if Syn is built with the `"derive"` or
172 /// `"full"` feature.*
173 pub Lit(ExprLit {
174 pub attrs: Vec<Attribute>,
175 pub lit: Lit,
176 }),
177
178 /// A cast expression: `foo as f64`.
179 ///
180 /// *This type is available if Syn is built with the `"derive"` or
181 /// `"full"` feature.*
182 pub Cast(ExprCast {
183 pub attrs: Vec<Attribute>,
184 pub expr: Box<Expr>,
185 pub as_token: Token![as],
186 pub ty: Box<Type>,
187 }),
188
189 /// A type ascription expression: `foo: f64`.
190 ///
191 /// *This type is available if Syn is built with the `"full"` feature.*
192 pub Type(ExprType #full {
193 pub attrs: Vec<Attribute>,
194 pub expr: Box<Expr>,
195 pub colon_token: Token![:],
196 pub ty: Box<Type>,
197 }),
198
199 /// A `let` guard: `let Some(x) = opt`.
200 ///
201 /// *This type is available if Syn is built with the `"full"` feature.*
202 pub Let(ExprLet #full {
203 pub attrs: Vec<Attribute>,
204 pub let_token: Token![let],
205 pub pats: Punctuated<Pat, Token![|]>,
206 pub eq_token: Token![=],
207 pub expr: Box<Expr>,
208 }),
209
210 /// An `if` expression with an optional `else` block: `if expr { ... }
211 /// else { ... }`.
212 ///
213 /// The `else` branch expression may only be an `If` or `Block`
214 /// expression, not any of the other types of expression.
215 ///
216 /// *This type is available if Syn is built with the `"full"` feature.*
217 pub If(ExprIf #full {
218 pub attrs: Vec<Attribute>,
219 pub if_token: Token![if],
220 pub cond: Box<Expr>,
221 pub then_branch: Block,
222 pub else_branch: Option<(Token![else], Box<Expr>)>,
223 }),
224
225 /// A while loop: `while expr { ... }`.
226 ///
227 /// *This type is available if Syn is built with the `"full"` feature.*
228 pub While(ExprWhile #full {
229 pub attrs: Vec<Attribute>,
230 pub label: Option<Label>,
231 pub while_token: Token![while],
232 pub cond: Box<Expr>,
233 pub body: Block,
234 }),
235
236 /// A for loop: `for pat in expr { ... }`.
237 ///
238 /// *This type is available if Syn is built with the `"full"` feature.*
239 pub ForLoop(ExprForLoop #full {
240 pub attrs: Vec<Attribute>,
241 pub label: Option<Label>,
242 pub for_token: Token![for],
243 pub pat: Box<Pat>,
244 pub in_token: Token![in],
245 pub expr: Box<Expr>,
246 pub body: Block,
247 }),
248
249 /// Conditionless loop: `loop { ... }`.
250 ///
251 /// *This type is available if Syn is built with the `"full"` feature.*
252 pub Loop(ExprLoop #full {
253 pub attrs: Vec<Attribute>,
254 pub label: Option<Label>,
255 pub loop_token: Token![loop],
256 pub body: Block,
257 }),
258
259 /// A `match` expression: `match n { Some(n) => {}, None => {} }`.
260 ///
261 /// *This type is available if Syn is built with the `"full"` feature.*
262 pub Match(ExprMatch #full {
263 pub attrs: Vec<Attribute>,
264 pub match_token: Token![match],
265 pub expr: Box<Expr>,
266 pub brace_token: token::Brace,
267 pub arms: Vec<Arm>,
268 }),
269
270 /// A closure expression: `|a, b| a + b`.
271 ///
272 /// *This type is available if Syn is built with the `"full"` feature.*
273 pub Closure(ExprClosure #full {
274 pub attrs: Vec<Attribute>,
275 pub asyncness: Option<Token![async]>,
276 pub movability: Option<Token![static]>,
277 pub capture: Option<Token![move]>,
278 pub or1_token: Token![|],
279 pub inputs: Punctuated<FnArg, Token![,]>,
280 pub or2_token: Token![|],
281 pub output: ReturnType,
282 pub body: Box<Expr>,
283 }),
284
285 /// An unsafe block: `unsafe { ... }`.
286 ///
287 /// *This type is available if Syn is built with the `"full"` feature.*
288 pub Unsafe(ExprUnsafe #full {
289 pub attrs: Vec<Attribute>,
290 pub unsafe_token: Token![unsafe],
291 pub block: Block,
292 }),
293
294 /// A blocked scope: `{ ... }`.
295 ///
296 /// *This type is available if Syn is built with the `"full"` feature.*
297 pub Block(ExprBlock #full {
298 pub attrs: Vec<Attribute>,
299 pub label: Option<Label>,
300 pub block: Block,
301 }),
302
303 /// An assignment expression: `a = compute()`.
304 ///
305 /// *This type is available if Syn is built with the `"full"` feature.*
306 pub Assign(ExprAssign #full {
307 pub attrs: Vec<Attribute>,
308 pub left: Box<Expr>,
309 pub eq_token: Token![=],
310 pub right: Box<Expr>,
311 }),
312
313 /// A compound assignment expression: `counter += 1`.
314 ///
315 /// *This type is available if Syn is built with the `"full"` feature.*
316 pub AssignOp(ExprAssignOp #full {
317 pub attrs: Vec<Attribute>,
318 pub left: Box<Expr>,
319 pub op: BinOp,
320 pub right: Box<Expr>,
321 }),
322
323 /// Access of a named struct field (`obj.k`) or unnamed tuple struct
324 /// field (`obj.0`).
325 ///
326 /// *This type is available if Syn is built with the `"full"` feature.*
327 pub Field(ExprField {
328 pub attrs: Vec<Attribute>,
329 pub base: Box<Expr>,
330 pub dot_token: Token![.],
331 pub member: Member,
332 }),
333
334 /// A square bracketed indexing expression: `vector[2]`.
335 ///
336 /// *This type is available if Syn is built with the `"derive"` or
337 /// `"full"` feature.*
338 pub Index(ExprIndex {
339 pub attrs: Vec<Attribute>,
340 pub expr: Box<Expr>,
341 pub bracket_token: token::Bracket,
342 pub index: Box<Expr>,
343 }),
344
345 /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`.
346 ///
347 /// *This type is available if Syn is built with the `"full"` feature.*
348 pub Range(ExprRange #full {
349 pub attrs: Vec<Attribute>,
350 pub from: Option<Box<Expr>>,
351 pub limits: RangeLimits,
352 pub to: Option<Box<Expr>>,
353 }),
354
355 /// A path like `std::mem::replace` possibly containing generic
356 /// parameters and a qualified self-type.
357 ///
358 /// A plain identifier like `x` is a path of length 1.
359 ///
360 /// *This type is available if Syn is built with the `"derive"` or
361 /// `"full"` feature.*
362 pub Path(ExprPath {
363 pub attrs: Vec<Attribute>,
364 pub qself: Option<QSelf>,
365 pub path: Path,
366 }),
367
368 /// A referencing operation: `&a` or `&mut a`.
369 ///
370 /// *This type is available if Syn is built with the `"full"` feature.*
371 pub Reference(ExprReference #full {
372 pub attrs: Vec<Attribute>,
373 pub and_token: Token![&],
374 pub mutability: Option<Token![mut]>,
375 pub expr: Box<Expr>,
376 }),
377
378 /// A `break`, with an optional label to break and an optional
379 /// expression.
380 ///
381 /// *This type is available if Syn is built with the `"full"` feature.*
382 pub Break(ExprBreak #full {
383 pub attrs: Vec<Attribute>,
384 pub break_token: Token![break],
385 pub label: Option<Lifetime>,
386 pub expr: Option<Box<Expr>>,
387 }),
388
389 /// A `continue`, with an optional label.
390 ///
391 /// *This type is available if Syn is built with the `"full"` feature.*
392 pub Continue(ExprContinue #full {
393 pub attrs: Vec<Attribute>,
394 pub continue_token: Token![continue],
395 pub label: Option<Lifetime>,
396 }),
397
398 /// A `return`, with an optional value to be returned.
399 ///
400 /// *This type is available if Syn is built with the `"full"` feature.*
401 pub Return(ExprReturn #full {
402 pub attrs: Vec<Attribute>,
403 pub return_token: Token![return],
404 pub expr: Option<Box<Expr>>,
405 }),
406
407 /// A macro invocation expression: `format!("{}", q)`.
408 ///
409 /// *This type is available if Syn is built with the `"full"` feature.*
410 pub Macro(ExprMacro #full {
411 pub attrs: Vec<Attribute>,
412 pub mac: Macro,
413 }),
414
415 /// A struct literal expression: `Point { x: 1, y: 1 }`.
416 ///
417 /// The `rest` provides the value of the remaining fields as in `S { a:
418 /// 1, b: 1, ..rest }`.
419 ///
420 /// *This type is available if Syn is built with the `"full"` feature.*
421 pub Struct(ExprStruct #full {
422 pub attrs: Vec<Attribute>,
423 pub path: Path,
424 pub brace_token: token::Brace,
425 pub fields: Punctuated<FieldValue, Token![,]>,
426 pub dot2_token: Option<Token![..]>,
427 pub rest: Option<Box<Expr>>,
428 }),
429
430 /// An array literal constructed from one repeated element: `[0u8; N]`.
431 ///
432 /// *This type is available if Syn is built with the `"full"` feature.*
433 pub Repeat(ExprRepeat #full {
434 pub attrs: Vec<Attribute>,
435 pub bracket_token: token::Bracket,
436 pub expr: Box<Expr>,
437 pub semi_token: Token![;],
438 pub len: Box<Expr>,
439 }),
440
441 /// A parenthesized expression: `(a + b)`.
442 ///
443 /// *This type is available if Syn is built with the `"full"` feature.*
444 pub Paren(ExprParen {
445 pub attrs: Vec<Attribute>,
446 pub paren_token: token::Paren,
447 pub expr: Box<Expr>,
448 }),
449
450 /// An expression contained within invisible delimiters.
451 ///
452 /// This variant is important for faithfully representing the precedence
453 /// of expressions and is related to `None`-delimited spans in a
454 /// `TokenStream`.
455 ///
456 /// *This type is available if Syn is built with the `"full"` feature.*
457 pub Group(ExprGroup #full {
458 pub attrs: Vec<Attribute>,
459 pub group_token: token::Group,
460 pub expr: Box<Expr>,
461 }),
462
463 /// A try-expression: `expr?`.
464 ///
465 /// *This type is available if Syn is built with the `"full"` feature.*
466 pub Try(ExprTry #full {
467 pub attrs: Vec<Attribute>,
468 pub expr: Box<Expr>,
469 pub question_token: Token![?],
470 }),
471
472 /// An async block: `async { ... }`.
473 ///
474 /// *This type is available if Syn is built with the `"full"` feature.*
475 pub Async(ExprAsync #full {
476 pub attrs: Vec<Attribute>,
477 pub async_token: Token![async],
478 pub capture: Option<Token![move]>,
479 pub block: Block,
480 }),
481
482 /// A try block: `try { ... }`.
483 ///
484 /// *This type is available if Syn is built with the `"full"` feature.*
485 pub TryBlock(ExprTryBlock #full {
486 pub attrs: Vec<Attribute>,
487 pub try_token: Token![try],
488 pub block: Block,
489 }),
490
491 /// A yield expression: `yield expr`.
492 ///
493 /// *This type is available if Syn is built with the `"full"` feature.*
494 pub Yield(ExprYield #full {
495 pub attrs: Vec<Attribute>,
496 pub yield_token: Token![yield],
497 pub expr: Option<Box<Expr>>,
498 }),
499
500 /// Tokens in expression position not interpreted by Syn.
501 ///
502 /// *This type is available if Syn is built with the `"derive"` or
503 /// `"full"` feature.*
504 pub Verbatim(ExprVerbatim #manual_extra_traits {
505 pub tts: TokenStream,
506 }),
507 }
508 }
509
510 #[cfg(feature = "extra-traits")]
511 impl Eq for ExprVerbatim {}
512
513 #[cfg(feature = "extra-traits")]
514 impl PartialEq for ExprVerbatim {
eq(&self, other: &Self) -> bool515 fn eq(&self, other: &Self) -> bool {
516 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
517 }
518 }
519
520 #[cfg(feature = "extra-traits")]
521 impl Hash for ExprVerbatim {
hash<H>(&self, state: &mut H) where H: Hasher,522 fn hash<H>(&self, state: &mut H)
523 where
524 H: Hasher,
525 {
526 TokenStreamHelper(&self.tts).hash(state);
527 }
528 }
529
530 impl Expr {
531 #[cfg(all(feature = "parsing", feature = "full"))]
replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute>532 fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
533 match *self {
534 Expr::Box(ExprBox { ref mut attrs, .. })
535 | Expr::InPlace(ExprInPlace { ref mut attrs, .. })
536 | Expr::Array(ExprArray { ref mut attrs, .. })
537 | Expr::Call(ExprCall { ref mut attrs, .. })
538 | Expr::MethodCall(ExprMethodCall { ref mut attrs, .. })
539 | Expr::Tuple(ExprTuple { ref mut attrs, .. })
540 | Expr::Binary(ExprBinary { ref mut attrs, .. })
541 | Expr::Unary(ExprUnary { ref mut attrs, .. })
542 | Expr::Lit(ExprLit { ref mut attrs, .. })
543 | Expr::Cast(ExprCast { ref mut attrs, .. })
544 | Expr::Type(ExprType { ref mut attrs, .. })
545 | Expr::Let(ExprLet { ref mut attrs, .. })
546 | Expr::If(ExprIf { ref mut attrs, .. })
547 | Expr::While(ExprWhile { ref mut attrs, .. })
548 | Expr::ForLoop(ExprForLoop { ref mut attrs, .. })
549 | Expr::Loop(ExprLoop { ref mut attrs, .. })
550 | Expr::Match(ExprMatch { ref mut attrs, .. })
551 | Expr::Closure(ExprClosure { ref mut attrs, .. })
552 | Expr::Unsafe(ExprUnsafe { ref mut attrs, .. })
553 | Expr::Block(ExprBlock { ref mut attrs, .. })
554 | Expr::Assign(ExprAssign { ref mut attrs, .. })
555 | Expr::AssignOp(ExprAssignOp { ref mut attrs, .. })
556 | Expr::Field(ExprField { ref mut attrs, .. })
557 | Expr::Index(ExprIndex { ref mut attrs, .. })
558 | Expr::Range(ExprRange { ref mut attrs, .. })
559 | Expr::Path(ExprPath { ref mut attrs, .. })
560 | Expr::Reference(ExprReference { ref mut attrs, .. })
561 | Expr::Break(ExprBreak { ref mut attrs, .. })
562 | Expr::Continue(ExprContinue { ref mut attrs, .. })
563 | Expr::Return(ExprReturn { ref mut attrs, .. })
564 | Expr::Macro(ExprMacro { ref mut attrs, .. })
565 | Expr::Struct(ExprStruct { ref mut attrs, .. })
566 | Expr::Repeat(ExprRepeat { ref mut attrs, .. })
567 | Expr::Paren(ExprParen { ref mut attrs, .. })
568 | Expr::Group(ExprGroup { ref mut attrs, .. })
569 | Expr::Try(ExprTry { ref mut attrs, .. })
570 | Expr::Async(ExprAsync { ref mut attrs, .. })
571 | Expr::TryBlock(ExprTryBlock { ref mut attrs, .. })
572 | Expr::Yield(ExprYield { ref mut attrs, .. }) => mem::replace(attrs, new),
573 Expr::Verbatim(_) => Vec::new(),
574 }
575 }
576 }
577
578 ast_enum! {
579 /// A struct or tuple struct field accessed in a struct literal or field
580 /// expression.
581 ///
582 /// *This type is available if Syn is built with the `"derive"` or `"full"`
583 /// feature.*
584 pub enum Member {
585 /// A named field like `self.x`.
586 Named(Ident),
587 /// An unnamed field like `self.0`.
588 Unnamed(Index),
589 }
590 }
591
592 ast_struct! {
593 /// The index of an unnamed tuple struct field.
594 ///
595 /// *This type is available if Syn is built with the `"derive"` or `"full"`
596 /// feature.*
597 pub struct Index #manual_extra_traits {
598 pub index: u32,
599 pub span: Span,
600 }
601 }
602
603 impl From<usize> for Index {
from(index: usize) -> Index604 fn from(index: usize) -> Index {
605 assert!(index < u32::max_value() as usize);
606 Index {
607 index: index as u32,
608 span: Span::call_site(),
609 }
610 }
611 }
612
613 #[cfg(feature = "extra-traits")]
614 impl Eq for Index {}
615
616 #[cfg(feature = "extra-traits")]
617 impl PartialEq for Index {
eq(&self, other: &Self) -> bool618 fn eq(&self, other: &Self) -> bool {
619 self.index == other.index
620 }
621 }
622
623 #[cfg(feature = "extra-traits")]
624 impl Hash for Index {
hash<H: Hasher>(&self, state: &mut H)625 fn hash<H: Hasher>(&self, state: &mut H) {
626 self.index.hash(state);
627 }
628 }
629
630 #[cfg(feature = "full")]
631 ast_struct! {
632 /// The `::<>` explicit type parameters passed to a method call:
633 /// `parse::<u64>()`.
634 ///
635 /// *This type is available if Syn is built with the `"full"` feature.*
636 pub struct MethodTurbofish {
637 pub colon2_token: Token![::],
638 pub lt_token: Token![<],
639 pub args: Punctuated<GenericMethodArgument, Token![,]>,
640 pub gt_token: Token![>],
641 }
642 }
643
644 #[cfg(feature = "full")]
645 ast_enum! {
646 /// An individual generic argument to a method, like `T`.
647 ///
648 /// *This type is available if Syn is built with the `"full"` feature.*
649 pub enum GenericMethodArgument {
650 /// A type argument.
651 Type(Type),
652 /// A const expression. Must be inside of a block.
653 ///
654 /// NOTE: Identity expressions are represented as Type arguments, as
655 /// they are indistinguishable syntactically.
656 Const(Expr),
657 }
658 }
659
660 #[cfg(feature = "full")]
661 ast_struct! {
662 /// A field-value pair in a struct literal.
663 ///
664 /// *This type is available if Syn is built with the `"full"` feature.*
665 pub struct FieldValue {
666 /// Attributes tagged on the field.
667 pub attrs: Vec<Attribute>,
668
669 /// Name or index of the field.
670 pub member: Member,
671
672 /// The colon in `Struct { x: x }`. If written in shorthand like
673 /// `Struct { x }`, there is no colon.
674 pub colon_token: Option<Token![:]>,
675
676 /// Value of the field.
677 pub expr: Expr,
678 }
679 }
680
681 #[cfg(feature = "full")]
682 ast_struct! {
683 /// A lifetime labeling a `for`, `while`, or `loop`.
684 ///
685 /// *This type is available if Syn is built with the `"full"` feature.*
686 pub struct Label {
687 pub name: Lifetime,
688 pub colon_token: Token![:],
689 }
690 }
691
692 #[cfg(feature = "full")]
693 ast_struct! {
694 /// A braced block containing Rust statements.
695 ///
696 /// *This type is available if Syn is built with the `"full"` feature.*
697 pub struct Block {
698 pub brace_token: token::Brace,
699 /// Statements in a block
700 pub stmts: Vec<Stmt>,
701 }
702 }
703
704 #[cfg(feature = "full")]
705 ast_enum! {
706 /// A statement, usually ending in a semicolon.
707 ///
708 /// *This type is available if Syn is built with the `"full"` feature.*
709 pub enum Stmt {
710 /// A local (let) binding.
711 Local(Local),
712
713 /// An item definition.
714 Item(Item),
715
716 /// Expr without trailing semicolon.
717 Expr(Expr),
718
719 /// Expression with trailing semicolon.
720 Semi(Expr, Token![;]),
721 }
722 }
723
724 #[cfg(feature = "full")]
725 ast_struct! {
726 /// A local `let` binding: `let x: u64 = s.parse()?`.
727 ///
728 /// *This type is available if Syn is built with the `"full"` feature.*
729 pub struct Local {
730 pub attrs: Vec<Attribute>,
731 pub let_token: Token![let],
732 pub pats: Punctuated<Pat, Token![|]>,
733 pub ty: Option<(Token![:], Box<Type>)>,
734 pub init: Option<(Token![=], Box<Expr>)>,
735 pub semi_token: Token![;],
736 }
737 }
738
739 #[cfg(feature = "full")]
740 ast_enum_of_structs! {
741 /// A pattern in a local binding, function signature, match expression, or
742 /// various other places.
743 ///
744 /// *This type is available if Syn is built with the `"full"` feature.*
745 ///
746 /// # Syntax tree enum
747 ///
748 /// This type is a [syntax tree enum].
749 ///
750 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
751 pub enum Pat {
752 /// A pattern that matches any value: `_`.
753 ///
754 /// *This type is available if Syn is built with the `"full"` feature.*
755 pub Wild(PatWild {
756 pub underscore_token: Token![_],
757 }),
758
759 /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
760 ///
761 /// *This type is available if Syn is built with the `"full"` feature.*
762 pub Ident(PatIdent {
763 pub by_ref: Option<Token![ref]>,
764 pub mutability: Option<Token![mut]>,
765 pub ident: Ident,
766 pub subpat: Option<(Token![@], Box<Pat>)>,
767 }),
768
769 /// A struct or struct variant pattern: `Variant { x, y, .. }`.
770 ///
771 /// *This type is available if Syn is built with the `"full"` feature.*
772 pub Struct(PatStruct {
773 pub path: Path,
774 pub brace_token: token::Brace,
775 pub fields: Punctuated<FieldPat, Token![,]>,
776 pub dot2_token: Option<Token![..]>,
777 }),
778
779 /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
780 ///
781 /// *This type is available if Syn is built with the `"full"` feature.*
782 pub TupleStruct(PatTupleStruct {
783 pub path: Path,
784 pub pat: PatTuple,
785 }),
786
787 /// A path pattern like `Color::Red`, optionally qualified with a
788 /// self-type.
789 ///
790 /// Unqualified path patterns can legally refer to variants, structs,
791 /// constants or associated constants. Qualified path patterns like
792 /// `<A>::B::C` and `<A as Trait>::B::C` can only legally refer to
793 /// associated constants.
794 ///
795 /// *This type is available if Syn is built with the `"full"` feature.*
796 pub Path(PatPath {
797 pub qself: Option<QSelf>,
798 pub path: Path,
799 }),
800
801 /// A tuple pattern: `(a, b)`.
802 ///
803 /// *This type is available if Syn is built with the `"full"` feature.*
804 pub Tuple(PatTuple {
805 pub paren_token: token::Paren,
806 pub front: Punctuated<Pat, Token![,]>,
807 pub dot2_token: Option<Token![..]>,
808 pub comma_token: Option<Token![,]>,
809 pub back: Punctuated<Pat, Token![,]>,
810 }),
811
812 /// A box pattern: `box v`.
813 ///
814 /// *This type is available if Syn is built with the `"full"` feature.*
815 pub Box(PatBox {
816 pub box_token: Token![box],
817 pub pat: Box<Pat>,
818 }),
819
820 /// A reference pattern: `&mut (first, second)`.
821 ///
822 /// *This type is available if Syn is built with the `"full"` feature.*
823 pub Ref(PatRef {
824 pub and_token: Token![&],
825 pub mutability: Option<Token![mut]>,
826 pub pat: Box<Pat>,
827 }),
828
829 /// A literal pattern: `0`.
830 ///
831 /// This holds an `Expr` rather than a `Lit` because negative numbers
832 /// are represented as an `Expr::Unary`.
833 ///
834 /// *This type is available if Syn is built with the `"full"` feature.*
835 pub Lit(PatLit {
836 pub expr: Box<Expr>,
837 }),
838
839 /// A range pattern: `1..=2`.
840 ///
841 /// *This type is available if Syn is built with the `"full"` feature.*
842 pub Range(PatRange {
843 pub lo: Box<Expr>,
844 pub limits: RangeLimits,
845 pub hi: Box<Expr>,
846 }),
847
848 /// A dynamically sized slice pattern: `[a, b, i.., y, z]`.
849 ///
850 /// *This type is available if Syn is built with the `"full"` feature.*
851 pub Slice(PatSlice {
852 pub bracket_token: token::Bracket,
853 pub front: Punctuated<Pat, Token![,]>,
854 pub middle: Option<Box<Pat>>,
855 pub dot2_token: Option<Token![..]>,
856 pub comma_token: Option<Token![,]>,
857 pub back: Punctuated<Pat, Token![,]>,
858 }),
859
860 /// A macro in expression position.
861 ///
862 /// *This type is available if Syn is built with the `"full"` feature.*
863 pub Macro(PatMacro {
864 pub mac: Macro,
865 }),
866
867 /// Tokens in pattern position not interpreted by Syn.
868 ///
869 /// *This type is available if Syn is built with the `"full"` feature.*
870 pub Verbatim(PatVerbatim #manual_extra_traits {
871 pub tts: TokenStream,
872 }),
873 }
874 }
875
876 #[cfg(all(feature = "full", feature = "extra-traits"))]
877 impl Eq for PatVerbatim {}
878
879 #[cfg(all(feature = "full", feature = "extra-traits"))]
880 impl PartialEq for PatVerbatim {
eq(&self, other: &Self) -> bool881 fn eq(&self, other: &Self) -> bool {
882 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
883 }
884 }
885
886 #[cfg(all(feature = "full", feature = "extra-traits"))]
887 impl Hash for PatVerbatim {
hash<H>(&self, state: &mut H) where H: Hasher,888 fn hash<H>(&self, state: &mut H)
889 where
890 H: Hasher,
891 {
892 TokenStreamHelper(&self.tts).hash(state);
893 }
894 }
895
896 #[cfg(feature = "full")]
897 ast_struct! {
898 /// One arm of a `match` expression: `0...10 => { return true; }`.
899 ///
900 /// As in:
901 ///
902 /// ```edition2018
903 /// # fn f() -> bool {
904 /// # let n = 0;
905 /// match n {
906 /// 0...10 => {
907 /// return true;
908 /// }
909 /// // ...
910 /// # _ => {}
911 /// }
912 /// # false
913 /// # }
914 /// ```
915 ///
916 /// *This type is available if Syn is built with the `"full"` feature.*
917 pub struct Arm {
918 pub attrs: Vec<Attribute>,
919 pub leading_vert: Option<Token![|]>,
920 pub pats: Punctuated<Pat, Token![|]>,
921 pub guard: Option<(Token![if], Box<Expr>)>,
922 pub fat_arrow_token: Token![=>],
923 pub body: Box<Expr>,
924 pub comma: Option<Token![,]>,
925 }
926 }
927
928 #[cfg(feature = "full")]
929 ast_enum! {
930 /// Limit types of a range, inclusive or exclusive.
931 ///
932 /// *This type is available if Syn is built with the `"full"` feature.*
933 #[cfg_attr(feature = "clone-impls", derive(Copy))]
934 pub enum RangeLimits {
935 /// Inclusive at the beginning, exclusive at the end.
936 HalfOpen(Token![..]),
937 /// Inclusive at the beginning and end.
938 Closed(Token![..=]),
939 }
940 }
941
942 #[cfg(feature = "full")]
943 ast_struct! {
944 /// A single field in a struct pattern.
945 ///
946 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated
947 /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token.
948 ///
949 /// *This type is available if Syn is built with the `"full"` feature.*
950 pub struct FieldPat {
951 pub attrs: Vec<Attribute>,
952 pub member: Member,
953 pub colon_token: Option<Token![:]>,
954 pub pat: Box<Pat>,
955 }
956 }
957
958 #[cfg(any(feature = "parsing", feature = "printing"))]
959 #[cfg(feature = "full")]
requires_terminator(expr: &Expr) -> bool960 fn requires_terminator(expr: &Expr) -> bool {
961 // see https://github.com/rust-lang/rust/blob/eb8f2586e/src/libsyntax/parse/classify.rs#L17-L37
962 match *expr {
963 Expr::Unsafe(..)
964 | Expr::Block(..)
965 | Expr::If(..)
966 | Expr::Match(..)
967 | Expr::While(..)
968 | Expr::Loop(..)
969 | Expr::ForLoop(..)
970 | Expr::Async(..)
971 | Expr::TryBlock(..) => false,
972 _ => true,
973 }
974 }
975
976 #[cfg(feature = "parsing")]
977 pub mod parsing {
978 use super::*;
979
980 #[cfg(feature = "full")]
981 use ext::IdentExt;
982 use parse::{Parse, ParseStream, Result};
983 use path;
984
985 // When we're parsing expressions which occur before blocks, like in an if
986 // statement's condition, we cannot parse a struct literal.
987 //
988 // Struct literals are ambiguous in certain positions
989 // https://github.com/rust-lang/rfcs/pull/92
990 #[derive(Copy, Clone)]
991 pub struct AllowStruct(bool);
992
993 #[derive(Copy, Clone, PartialEq, PartialOrd)]
994 enum Precedence {
995 Any,
996 Assign,
997 Range,
998 Or,
999 And,
1000 Compare,
1001 BitOr,
1002 BitXor,
1003 BitAnd,
1004 Shift,
1005 Arithmetic,
1006 Term,
1007 Cast,
1008 }
1009
1010 impl Precedence {
of(op: &BinOp) -> Self1011 fn of(op: &BinOp) -> Self {
1012 match *op {
1013 BinOp::Add(_) | BinOp::Sub(_) => Precedence::Arithmetic,
1014 BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Term,
1015 BinOp::And(_) => Precedence::And,
1016 BinOp::Or(_) => Precedence::Or,
1017 BinOp::BitXor(_) => Precedence::BitXor,
1018 BinOp::BitAnd(_) => Precedence::BitAnd,
1019 BinOp::BitOr(_) => Precedence::BitOr,
1020 BinOp::Shl(_) | BinOp::Shr(_) => Precedence::Shift,
1021 BinOp::Eq(_)
1022 | BinOp::Lt(_)
1023 | BinOp::Le(_)
1024 | BinOp::Ne(_)
1025 | BinOp::Ge(_)
1026 | BinOp::Gt(_) => Precedence::Compare,
1027 BinOp::AddEq(_)
1028 | BinOp::SubEq(_)
1029 | BinOp::MulEq(_)
1030 | BinOp::DivEq(_)
1031 | BinOp::RemEq(_)
1032 | BinOp::BitXorEq(_)
1033 | BinOp::BitAndEq(_)
1034 | BinOp::BitOrEq(_)
1035 | BinOp::ShlEq(_)
1036 | BinOp::ShrEq(_) => Precedence::Assign,
1037 }
1038 }
1039 }
1040
1041 impl Parse for Expr {
parse(input: ParseStream) -> Result<Self>1042 fn parse(input: ParseStream) -> Result<Self> {
1043 ambiguous_expr(input, AllowStruct(true))
1044 }
1045 }
1046
1047 #[cfg(feature = "full")]
expr_no_struct(input: ParseStream) -> Result<Expr>1048 fn expr_no_struct(input: ParseStream) -> Result<Expr> {
1049 ambiguous_expr(input, AllowStruct(false))
1050 }
1051
1052 #[cfg(feature = "full")]
parse_expr( input: ParseStream, mut lhs: Expr, allow_struct: AllowStruct, base: Precedence, ) -> Result<Expr>1053 fn parse_expr(
1054 input: ParseStream,
1055 mut lhs: Expr,
1056 allow_struct: AllowStruct,
1057 base: Precedence,
1058 ) -> Result<Expr> {
1059 loop {
1060 if input
1061 .fork()
1062 .parse::<BinOp>()
1063 .ok()
1064 .map_or(false, |op| Precedence::of(&op) >= base)
1065 {
1066 let op: BinOp = input.parse()?;
1067 let precedence = Precedence::of(&op);
1068 let mut rhs = unary_expr(input, allow_struct)?;
1069 loop {
1070 let next = peek_precedence(input);
1071 if next > precedence || next == precedence && precedence == Precedence::Assign {
1072 rhs = parse_expr(input, rhs, allow_struct, next)?;
1073 } else {
1074 break;
1075 }
1076 }
1077 lhs = if precedence == Precedence::Assign {
1078 Expr::AssignOp(ExprAssignOp {
1079 attrs: Vec::new(),
1080 left: Box::new(lhs),
1081 op: op,
1082 right: Box::new(rhs),
1083 })
1084 } else {
1085 Expr::Binary(ExprBinary {
1086 attrs: Vec::new(),
1087 left: Box::new(lhs),
1088 op: op,
1089 right: Box::new(rhs),
1090 })
1091 };
1092 } else if Precedence::Assign >= base
1093 && input.peek(Token![=])
1094 && !input.peek(Token![==])
1095 && !input.peek(Token![=>])
1096 {
1097 let eq_token: Token![=] = input.parse()?;
1098 let mut rhs = unary_expr(input, allow_struct)?;
1099 loop {
1100 let next = peek_precedence(input);
1101 if next >= Precedence::Assign {
1102 rhs = parse_expr(input, rhs, allow_struct, next)?;
1103 } else {
1104 break;
1105 }
1106 }
1107 lhs = Expr::Assign(ExprAssign {
1108 attrs: Vec::new(),
1109 left: Box::new(lhs),
1110 eq_token: eq_token,
1111 right: Box::new(rhs),
1112 });
1113 } else if Precedence::Range >= base && input.peek(Token![..]) {
1114 let limits: RangeLimits = input.parse()?;
1115 let rhs = if input.is_empty()
1116 || input.peek(Token![,])
1117 || input.peek(Token![;])
1118 || !allow_struct.0 && input.peek(token::Brace)
1119 {
1120 None
1121 } else {
1122 let mut rhs = unary_expr(input, allow_struct)?;
1123 loop {
1124 let next = peek_precedence(input);
1125 if next > Precedence::Range {
1126 rhs = parse_expr(input, rhs, allow_struct, next)?;
1127 } else {
1128 break;
1129 }
1130 }
1131 Some(rhs)
1132 };
1133 lhs = Expr::Range(ExprRange {
1134 attrs: Vec::new(),
1135 from: Some(Box::new(lhs)),
1136 limits: limits,
1137 to: rhs.map(Box::new),
1138 });
1139 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1140 let as_token: Token![as] = input.parse()?;
1141 let ty = input.call(Type::without_plus)?;
1142 lhs = Expr::Cast(ExprCast {
1143 attrs: Vec::new(),
1144 expr: Box::new(lhs),
1145 as_token: as_token,
1146 ty: Box::new(ty),
1147 });
1148 } else if Precedence::Cast >= base && input.peek(Token![:]) && !input.peek(Token![::]) {
1149 let colon_token: Token![:] = input.parse()?;
1150 let ty = input.call(Type::without_plus)?;
1151 lhs = Expr::Type(ExprType {
1152 attrs: Vec::new(),
1153 expr: Box::new(lhs),
1154 colon_token: colon_token,
1155 ty: Box::new(ty),
1156 });
1157 } else {
1158 break;
1159 }
1160 }
1161 Ok(lhs)
1162 }
1163
1164 #[cfg(not(feature = "full"))]
parse_expr( input: ParseStream, mut lhs: Expr, allow_struct: AllowStruct, base: Precedence, ) -> Result<Expr>1165 fn parse_expr(
1166 input: ParseStream,
1167 mut lhs: Expr,
1168 allow_struct: AllowStruct,
1169 base: Precedence,
1170 ) -> Result<Expr> {
1171 loop {
1172 if input
1173 .fork()
1174 .parse::<BinOp>()
1175 .ok()
1176 .map_or(false, |op| Precedence::of(&op) >= base)
1177 {
1178 let op: BinOp = input.parse()?;
1179 let precedence = Precedence::of(&op);
1180 let mut rhs = unary_expr(input, allow_struct)?;
1181 loop {
1182 let next = peek_precedence(input);
1183 if next > precedence || next == precedence && precedence == Precedence::Assign {
1184 rhs = parse_expr(input, rhs, allow_struct, next)?;
1185 } else {
1186 break;
1187 }
1188 }
1189 lhs = Expr::Binary(ExprBinary {
1190 attrs: Vec::new(),
1191 left: Box::new(lhs),
1192 op: op,
1193 right: Box::new(rhs),
1194 });
1195 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1196 let as_token: Token![as] = input.parse()?;
1197 let ty = input.call(Type::without_plus)?;
1198 lhs = Expr::Cast(ExprCast {
1199 attrs: Vec::new(),
1200 expr: Box::new(lhs),
1201 as_token: as_token,
1202 ty: Box::new(ty),
1203 });
1204 } else {
1205 break;
1206 }
1207 }
1208 Ok(lhs)
1209 }
1210
peek_precedence(input: ParseStream) -> Precedence1211 fn peek_precedence(input: ParseStream) -> Precedence {
1212 if let Ok(op) = input.fork().parse() {
1213 Precedence::of(&op)
1214 } else if input.peek(Token![=]) && !input.peek(Token![=>]) {
1215 Precedence::Assign
1216 } else if input.peek(Token![..]) {
1217 Precedence::Range
1218 } else if input.peek(Token![as]) || input.peek(Token![:]) && !input.peek(Token![::]) {
1219 Precedence::Cast
1220 } else {
1221 Precedence::Any
1222 }
1223 }
1224
1225 // Parse an arbitrary expression.
ambiguous_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1226 fn ambiguous_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1227 let lhs = unary_expr(input, allow_struct)?;
1228 parse_expr(input, lhs, allow_struct, Precedence::Any)
1229 }
1230
1231 // <UnOp> <trailer>
1232 // & <trailer>
1233 // &mut <trailer>
1234 // box <trailer>
1235 #[cfg(feature = "full")]
unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1236 fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1237 let ahead = input.fork();
1238 ahead.call(Attribute::parse_outer)?;
1239 if ahead.peek(Token![&])
1240 || ahead.peek(Token![box])
1241 || ahead.peek(Token![*])
1242 || ahead.peek(Token![!])
1243 || ahead.peek(Token![-])
1244 {
1245 let attrs = input.call(Attribute::parse_outer)?;
1246 if input.peek(Token![&]) {
1247 Ok(Expr::Reference(ExprReference {
1248 attrs: attrs,
1249 and_token: input.parse()?,
1250 mutability: input.parse()?,
1251 expr: Box::new(unary_expr(input, allow_struct)?),
1252 }))
1253 } else if input.peek(Token![box]) {
1254 Ok(Expr::Box(ExprBox {
1255 attrs: attrs,
1256 box_token: input.parse()?,
1257 expr: Box::new(unary_expr(input, allow_struct)?),
1258 }))
1259 } else {
1260 Ok(Expr::Unary(ExprUnary {
1261 attrs: attrs,
1262 op: input.parse()?,
1263 expr: Box::new(unary_expr(input, allow_struct)?),
1264 }))
1265 }
1266 } else {
1267 trailer_expr(input, allow_struct)
1268 }
1269 }
1270
1271 #[cfg(not(feature = "full"))]
unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1272 fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1273 let ahead = input.fork();
1274 ahead.call(Attribute::parse_outer)?;
1275 if ahead.peek(Token![*]) || ahead.peek(Token![!]) || ahead.peek(Token![-]) {
1276 Ok(Expr::Unary(ExprUnary {
1277 attrs: input.call(Attribute::parse_outer)?,
1278 op: input.parse()?,
1279 expr: Box::new(unary_expr(input, allow_struct)?),
1280 }))
1281 } else {
1282 trailer_expr(input, allow_struct)
1283 }
1284 }
1285
1286 // <atom> (..<args>) ...
1287 // <atom> . <ident> (..<args>) ...
1288 // <atom> . <ident> ...
1289 // <atom> . <lit> ...
1290 // <atom> [ <expr> ] ...
1291 // <atom> ? ...
1292 #[cfg(feature = "full")]
trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1293 fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1294 if input.peek(token::Group) {
1295 return input.call(expr_group).map(Expr::Group);
1296 }
1297
1298 let outer_attrs = input.call(Attribute::parse_outer)?;
1299
1300 let atom = atom_expr(input, allow_struct)?;
1301 let mut e = trailer_helper(input, atom)?;
1302
1303 let inner_attrs = e.replace_attrs(Vec::new());
1304 let attrs = private::attrs(outer_attrs, inner_attrs);
1305 e.replace_attrs(attrs);
1306 Ok(e)
1307 }
1308
1309 #[cfg(feature = "full")]
trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr>1310 fn trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr> {
1311 loop {
1312 if input.peek(token::Paren) {
1313 let content;
1314 e = Expr::Call(ExprCall {
1315 attrs: Vec::new(),
1316 func: Box::new(e),
1317 paren_token: parenthesized!(content in input),
1318 args: content.parse_terminated(Expr::parse)?,
1319 });
1320 } else if input.peek(Token![.]) && !input.peek(Token![..]) {
1321 let dot_token: Token![.] = input.parse()?;
1322 let member: Member = input.parse()?;
1323 let turbofish = if member.is_named() && input.peek(Token![::]) {
1324 Some(MethodTurbofish {
1325 colon2_token: input.parse()?,
1326 lt_token: input.parse()?,
1327 args: {
1328 let mut args = Punctuated::new();
1329 loop {
1330 if input.peek(Token![>]) {
1331 break;
1332 }
1333 let value = input.call(generic_method_argument)?;
1334 args.push_value(value);
1335 if input.peek(Token![>]) {
1336 break;
1337 }
1338 let punct = input.parse()?;
1339 args.push_punct(punct);
1340 }
1341 args
1342 },
1343 gt_token: input.parse()?,
1344 })
1345 } else {
1346 None
1347 };
1348
1349 if turbofish.is_some() || input.peek(token::Paren) {
1350 if let Member::Named(method) = member {
1351 let content;
1352 e = Expr::MethodCall(ExprMethodCall {
1353 attrs: Vec::new(),
1354 receiver: Box::new(e),
1355 dot_token: dot_token,
1356 method: method,
1357 turbofish: turbofish,
1358 paren_token: parenthesized!(content in input),
1359 args: content.parse_terminated(Expr::parse)?,
1360 });
1361 continue;
1362 }
1363 }
1364
1365 e = Expr::Field(ExprField {
1366 attrs: Vec::new(),
1367 base: Box::new(e),
1368 dot_token: dot_token,
1369 member: member,
1370 });
1371 } else if input.peek(token::Bracket) {
1372 let content;
1373 e = Expr::Index(ExprIndex {
1374 attrs: Vec::new(),
1375 expr: Box::new(e),
1376 bracket_token: bracketed!(content in input),
1377 index: content.parse()?,
1378 });
1379 } else if input.peek(Token![?]) {
1380 e = Expr::Try(ExprTry {
1381 attrs: Vec::new(),
1382 expr: Box::new(e),
1383 question_token: input.parse()?,
1384 });
1385 } else {
1386 break;
1387 }
1388 }
1389 Ok(e)
1390 }
1391
1392 #[cfg(not(feature = "full"))]
trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1393 fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1394 let mut e = atom_expr(input, allow_struct)?;
1395
1396 loop {
1397 if input.peek(token::Paren) {
1398 let content;
1399 e = Expr::Call(ExprCall {
1400 attrs: Vec::new(),
1401 func: Box::new(e),
1402 paren_token: parenthesized!(content in input),
1403 args: content.parse_terminated(Expr::parse)?,
1404 });
1405 } else if input.peek(Token![.]) {
1406 e = Expr::Field(ExprField {
1407 attrs: Vec::new(),
1408 base: Box::new(e),
1409 dot_token: input.parse()?,
1410 member: input.parse()?,
1411 });
1412 } else if input.peek(token::Bracket) {
1413 let content;
1414 e = Expr::Index(ExprIndex {
1415 attrs: Vec::new(),
1416 expr: Box::new(e),
1417 bracket_token: bracketed!(content in input),
1418 index: content.parse()?,
1419 });
1420 } else {
1421 break;
1422 }
1423 }
1424
1425 Ok(e)
1426 }
1427
1428 // Parse all atomic expressions which don't have to worry about precedence
1429 // interactions, as they are fully contained.
1430 #[cfg(feature = "full")]
atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1431 fn atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1432 if input.peek(token::Group) {
1433 input.call(expr_group).map(Expr::Group)
1434 } else if input.peek(Lit) {
1435 input.parse().map(Expr::Lit)
1436 } else if input.peek(Token![async])
1437 && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace))
1438 {
1439 input.call(expr_async).map(Expr::Async)
1440 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1441 input.call(expr_try_block).map(Expr::TryBlock)
1442 } else if input.peek(Token![|])
1443 || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move]))
1444 || input.peek(Token![static])
1445 || input.peek(Token![move])
1446 {
1447 expr_closure(input, allow_struct).map(Expr::Closure)
1448 } else if input.peek(Ident)
1449 || input.peek(Token![::])
1450 || input.peek(Token![<])
1451 || input.peek(Token![self])
1452 || input.peek(Token![Self])
1453 || input.peek(Token![super])
1454 || input.peek(Token![extern])
1455 || input.peek(Token![crate])
1456 {
1457 path_or_macro_or_struct(input, allow_struct)
1458 } else if input.peek(token::Paren) {
1459 paren_or_tuple(input)
1460 } else if input.peek(Token![break]) {
1461 expr_break(input, allow_struct).map(Expr::Break)
1462 } else if input.peek(Token![continue]) {
1463 input.call(expr_continue).map(Expr::Continue)
1464 } else if input.peek(Token![return]) {
1465 expr_ret(input, allow_struct).map(Expr::Return)
1466 } else if input.peek(token::Bracket) {
1467 array_or_repeat(input)
1468 } else if input.peek(Token![let]) {
1469 input.call(expr_let).map(Expr::Let)
1470 } else if input.peek(Token![if]) {
1471 input.parse().map(Expr::If)
1472 } else if input.peek(Token![while]) {
1473 input.parse().map(Expr::While)
1474 } else if input.peek(Token![for]) {
1475 input.parse().map(Expr::ForLoop)
1476 } else if input.peek(Token![loop]) {
1477 input.parse().map(Expr::Loop)
1478 } else if input.peek(Token![match]) {
1479 input.parse().map(Expr::Match)
1480 } else if input.peek(Token![yield]) {
1481 input.call(expr_yield).map(Expr::Yield)
1482 } else if input.peek(Token![unsafe]) {
1483 input.call(expr_unsafe).map(Expr::Unsafe)
1484 } else if input.peek(token::Brace) {
1485 input.call(expr_block).map(Expr::Block)
1486 } else if input.peek(Token![..]) {
1487 expr_range(input, allow_struct).map(Expr::Range)
1488 } else if input.peek(Lifetime) {
1489 let the_label: Label = input.parse()?;
1490 let mut expr = if input.peek(Token![while]) {
1491 Expr::While(input.parse()?)
1492 } else if input.peek(Token![for]) {
1493 Expr::ForLoop(input.parse()?)
1494 } else if input.peek(Token![loop]) {
1495 Expr::Loop(input.parse()?)
1496 } else if input.peek(token::Brace) {
1497 Expr::Block(input.call(expr_block)?)
1498 } else {
1499 return Err(input.error("expected loop or block expression"));
1500 };
1501 match expr {
1502 Expr::While(ExprWhile { ref mut label, .. })
1503 | Expr::ForLoop(ExprForLoop { ref mut label, .. })
1504 | Expr::Loop(ExprLoop { ref mut label, .. })
1505 | Expr::Block(ExprBlock { ref mut label, .. }) => *label = Some(the_label),
1506 _ => unreachable!(),
1507 }
1508 Ok(expr)
1509 } else {
1510 Err(input.error("expected expression"))
1511 }
1512 }
1513
1514 #[cfg(not(feature = "full"))]
atom_expr(input: ParseStream, _allow_struct: AllowStruct) -> Result<Expr>1515 fn atom_expr(input: ParseStream, _allow_struct: AllowStruct) -> Result<Expr> {
1516 if input.peek(Lit) {
1517 input.parse().map(Expr::Lit)
1518 } else if input.peek(token::Paren) {
1519 input.call(expr_paren).map(Expr::Paren)
1520 } else if input.peek(Ident)
1521 || input.peek(Token![::])
1522 || input.peek(Token![<])
1523 || input.peek(Token![self])
1524 || input.peek(Token![Self])
1525 || input.peek(Token![super])
1526 || input.peek(Token![extern])
1527 || input.peek(Token![crate])
1528 {
1529 input.parse().map(Expr::Path)
1530 } else {
1531 Err(input.error("unsupported expression; enable syn's features=[\"full\"]"))
1532 }
1533 }
1534
1535 #[cfg(feature = "full")]
path_or_macro_or_struct(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1536 fn path_or_macro_or_struct(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1537 let expr: ExprPath = input.parse()?;
1538 if expr.qself.is_some() {
1539 return Ok(Expr::Path(expr));
1540 }
1541
1542 if input.peek(Token![!]) && !input.peek(Token![!=]) {
1543 let mut contains_arguments = false;
1544 for segment in &expr.path.segments {
1545 match segment.arguments {
1546 PathArguments::None => {}
1547 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
1548 contains_arguments = true;
1549 }
1550 }
1551 }
1552
1553 if !contains_arguments {
1554 let bang_token: Token![!] = input.parse()?;
1555 let (delimiter, tts) = mac::parse_delimiter(input)?;
1556 return Ok(Expr::Macro(ExprMacro {
1557 attrs: Vec::new(),
1558 mac: Macro {
1559 path: expr.path,
1560 bang_token: bang_token,
1561 delimiter: delimiter,
1562 tts: tts,
1563 },
1564 }));
1565 }
1566 }
1567
1568 if allow_struct.0 && input.peek(token::Brace) {
1569 let outer_attrs = Vec::new();
1570 expr_struct_helper(input, outer_attrs, expr.path).map(Expr::Struct)
1571 } else {
1572 Ok(Expr::Path(expr))
1573 }
1574 }
1575
1576 #[cfg(feature = "full")]
paren_or_tuple(input: ParseStream) -> Result<Expr>1577 fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
1578 let content;
1579 let paren_token = parenthesized!(content in input);
1580 let inner_attrs = content.call(Attribute::parse_inner)?;
1581 if content.is_empty() {
1582 return Ok(Expr::Tuple(ExprTuple {
1583 attrs: inner_attrs,
1584 paren_token: paren_token,
1585 elems: Punctuated::new(),
1586 }));
1587 }
1588
1589 let first: Expr = content.parse()?;
1590 if content.is_empty() {
1591 return Ok(Expr::Paren(ExprParen {
1592 attrs: inner_attrs,
1593 paren_token: paren_token,
1594 expr: Box::new(first),
1595 }));
1596 }
1597
1598 let mut elems = Punctuated::new();
1599 elems.push_value(first);
1600 while !content.is_empty() {
1601 let punct = content.parse()?;
1602 elems.push_punct(punct);
1603 if content.is_empty() {
1604 break;
1605 }
1606 let value = content.parse()?;
1607 elems.push_value(value);
1608 }
1609 Ok(Expr::Tuple(ExprTuple {
1610 attrs: inner_attrs,
1611 paren_token: paren_token,
1612 elems: elems,
1613 }))
1614 }
1615
1616 #[cfg(feature = "full")]
array_or_repeat(input: ParseStream) -> Result<Expr>1617 fn array_or_repeat(input: ParseStream) -> Result<Expr> {
1618 let content;
1619 let bracket_token = bracketed!(content in input);
1620 let inner_attrs = content.call(Attribute::parse_inner)?;
1621 if content.is_empty() {
1622 return Ok(Expr::Array(ExprArray {
1623 attrs: inner_attrs,
1624 bracket_token: bracket_token,
1625 elems: Punctuated::new(),
1626 }));
1627 }
1628
1629 let first: Expr = content.parse()?;
1630 if content.is_empty() || content.peek(Token![,]) {
1631 let mut elems = Punctuated::new();
1632 elems.push_value(first);
1633 while !content.is_empty() {
1634 let punct = content.parse()?;
1635 elems.push_punct(punct);
1636 if content.is_empty() {
1637 break;
1638 }
1639 let value = content.parse()?;
1640 elems.push_value(value);
1641 }
1642 Ok(Expr::Array(ExprArray {
1643 attrs: inner_attrs,
1644 bracket_token: bracket_token,
1645 elems: elems,
1646 }))
1647 } else if content.peek(Token![;]) {
1648 let semi_token: Token![;] = content.parse()?;
1649 let len: Expr = content.parse()?;
1650 Ok(Expr::Repeat(ExprRepeat {
1651 attrs: inner_attrs,
1652 bracket_token: bracket_token,
1653 expr: Box::new(first),
1654 semi_token: semi_token,
1655 len: Box::new(len),
1656 }))
1657 } else {
1658 Err(content.error("expected `,` or `;`"))
1659 }
1660 }
1661
1662 #[cfg(feature = "full")]
expr_early(input: ParseStream) -> Result<Expr>1663 fn expr_early(input: ParseStream) -> Result<Expr> {
1664 let mut attrs = input.call(Attribute::parse_outer)?;
1665 let mut expr = if input.peek(Token![if]) {
1666 Expr::If(input.parse()?)
1667 } else if input.peek(Token![while]) {
1668 Expr::While(input.parse()?)
1669 } else if input.peek(Token![for]) {
1670 Expr::ForLoop(input.parse()?)
1671 } else if input.peek(Token![loop]) {
1672 Expr::Loop(input.parse()?)
1673 } else if input.peek(Token![match]) {
1674 Expr::Match(input.parse()?)
1675 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1676 Expr::TryBlock(input.call(expr_try_block)?)
1677 } else if input.peek(Token![unsafe]) {
1678 Expr::Unsafe(input.call(expr_unsafe)?)
1679 } else if input.peek(token::Brace) {
1680 Expr::Block(input.call(expr_block)?)
1681 } else {
1682 let allow_struct = AllowStruct(true);
1683 let mut expr = unary_expr(input, allow_struct)?;
1684
1685 attrs.extend(expr.replace_attrs(Vec::new()));
1686 expr.replace_attrs(attrs);
1687
1688 return parse_expr(input, expr, allow_struct, Precedence::Any);
1689 };
1690
1691 if input.peek(Token![.]) || input.peek(Token![?]) {
1692 expr = trailer_helper(input, expr)?;
1693
1694 attrs.extend(expr.replace_attrs(Vec::new()));
1695 expr.replace_attrs(attrs);
1696
1697 let allow_struct = AllowStruct(true);
1698 return parse_expr(input, expr, allow_struct, Precedence::Any);
1699 }
1700
1701 attrs.extend(expr.replace_attrs(Vec::new()));
1702 expr.replace_attrs(attrs);
1703 Ok(expr)
1704 }
1705
1706 impl Parse for ExprLit {
parse(input: ParseStream) -> Result<Self>1707 fn parse(input: ParseStream) -> Result<Self> {
1708 Ok(ExprLit {
1709 attrs: Vec::new(),
1710 lit: input.parse()?,
1711 })
1712 }
1713 }
1714
1715 #[cfg(feature = "full")]
expr_group(input: ParseStream) -> Result<ExprGroup>1716 fn expr_group(input: ParseStream) -> Result<ExprGroup> {
1717 let group = private::parse_group(input)?;
1718 Ok(ExprGroup {
1719 attrs: Vec::new(),
1720 group_token: group.token,
1721 expr: group.content.parse()?,
1722 })
1723 }
1724
1725 #[cfg(not(feature = "full"))]
expr_paren(input: ParseStream) -> Result<ExprParen>1726 fn expr_paren(input: ParseStream) -> Result<ExprParen> {
1727 let content;
1728 Ok(ExprParen {
1729 attrs: Vec::new(),
1730 paren_token: parenthesized!(content in input),
1731 expr: content.parse()?,
1732 })
1733 }
1734
1735 #[cfg(feature = "full")]
generic_method_argument(input: ParseStream) -> Result<GenericMethodArgument>1736 fn generic_method_argument(input: ParseStream) -> Result<GenericMethodArgument> {
1737 // TODO parse const generics as well
1738 input.parse().map(GenericMethodArgument::Type)
1739 }
1740
1741 #[cfg(feature = "full")]
expr_let(input: ParseStream) -> Result<ExprLet>1742 fn expr_let(input: ParseStream) -> Result<ExprLet> {
1743 Ok(ExprLet {
1744 attrs: Vec::new(),
1745 let_token: input.parse()?,
1746 pats: {
1747 let mut pats = Punctuated::new();
1748 input.parse::<Option<Token![|]>>()?;
1749 let value: Pat = input.parse()?;
1750 pats.push_value(value);
1751 while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
1752 let punct = input.parse()?;
1753 pats.push_punct(punct);
1754 let value: Pat = input.parse()?;
1755 pats.push_value(value);
1756 }
1757 pats
1758 },
1759 eq_token: input.parse()?,
1760 expr: Box::new(input.call(expr_no_struct)?),
1761 })
1762 }
1763
1764 #[cfg(feature = "full")]
1765 impl Parse for ExprIf {
parse(input: ParseStream) -> Result<Self>1766 fn parse(input: ParseStream) -> Result<Self> {
1767 Ok(ExprIf {
1768 attrs: Vec::new(),
1769 if_token: input.parse()?,
1770 cond: Box::new(input.call(expr_no_struct)?),
1771 then_branch: input.parse()?,
1772 else_branch: {
1773 if input.peek(Token![else]) {
1774 Some(input.call(else_block)?)
1775 } else {
1776 None
1777 }
1778 },
1779 })
1780 }
1781 }
1782
1783 #[cfg(feature = "full")]
else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)>1784 fn else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)> {
1785 let else_token: Token![else] = input.parse()?;
1786
1787 let lookahead = input.lookahead1();
1788 let else_branch = if input.peek(Token![if]) {
1789 input.parse().map(Expr::If)?
1790 } else if input.peek(token::Brace) {
1791 Expr::Block(ExprBlock {
1792 attrs: Vec::new(),
1793 label: None,
1794 block: input.parse()?,
1795 })
1796 } else {
1797 return Err(lookahead.error());
1798 };
1799
1800 Ok((else_token, Box::new(else_branch)))
1801 }
1802
1803 #[cfg(feature = "full")]
1804 impl Parse for ExprForLoop {
parse(input: ParseStream) -> Result<Self>1805 fn parse(input: ParseStream) -> Result<Self> {
1806 let label: Option<Label> = input.parse()?;
1807 let for_token: Token![for] = input.parse()?;
1808 let pat: Pat = input.parse()?;
1809 let in_token: Token![in] = input.parse()?;
1810 let expr: Expr = input.call(expr_no_struct)?;
1811
1812 let content;
1813 let brace_token = braced!(content in input);
1814 let inner_attrs = content.call(Attribute::parse_inner)?;
1815 let stmts = content.call(Block::parse_within)?;
1816
1817 Ok(ExprForLoop {
1818 attrs: inner_attrs,
1819 label: label,
1820 for_token: for_token,
1821 pat: Box::new(pat),
1822 in_token: in_token,
1823 expr: Box::new(expr),
1824 body: Block {
1825 brace_token: brace_token,
1826 stmts: stmts,
1827 },
1828 })
1829 }
1830 }
1831
1832 #[cfg(feature = "full")]
1833 impl Parse for ExprLoop {
parse(input: ParseStream) -> Result<Self>1834 fn parse(input: ParseStream) -> Result<Self> {
1835 let label: Option<Label> = input.parse()?;
1836 let loop_token: Token![loop] = input.parse()?;
1837
1838 let content;
1839 let brace_token = braced!(content in input);
1840 let inner_attrs = content.call(Attribute::parse_inner)?;
1841 let stmts = content.call(Block::parse_within)?;
1842
1843 Ok(ExprLoop {
1844 attrs: inner_attrs,
1845 label: label,
1846 loop_token: loop_token,
1847 body: Block {
1848 brace_token: brace_token,
1849 stmts: stmts,
1850 },
1851 })
1852 }
1853 }
1854
1855 #[cfg(feature = "full")]
1856 impl Parse for ExprMatch {
parse(input: ParseStream) -> Result<Self>1857 fn parse(input: ParseStream) -> Result<Self> {
1858 let match_token: Token![match] = input.parse()?;
1859 let expr = expr_no_struct(input)?;
1860
1861 let content;
1862 let brace_token = braced!(content in input);
1863 let inner_attrs = content.call(Attribute::parse_inner)?;
1864
1865 let mut arms = Vec::new();
1866 while !content.is_empty() {
1867 arms.push(content.call(Arm::parse)?);
1868 }
1869
1870 Ok(ExprMatch {
1871 attrs: inner_attrs,
1872 match_token: match_token,
1873 expr: Box::new(expr),
1874 brace_token: brace_token,
1875 arms: arms,
1876 })
1877 }
1878 }
1879
1880 #[cfg(all(feature = "full", feature = "printing"))]
1881 impl Parse for ExprInPlace {
parse(input: ParseStream) -> Result<Self>1882 fn parse(input: ParseStream) -> Result<Self> {
1883 let msg = "placement expression has been removed from Rust and is no longer parsed";
1884 Err(input.error(msg))
1885 }
1886 }
1887
1888 macro_rules! impl_by_parsing_expr {
1889 (
1890 $(
1891 $expr_type:ty, $variant:ident, $msg:expr,
1892 )*
1893 ) => {
1894 $(
1895 #[cfg(all(feature = "full", feature = "printing"))]
1896 impl Parse for $expr_type {
1897 fn parse(input: ParseStream) -> Result<Self> {
1898 let mut expr: Expr = input.parse()?;
1899 loop {
1900 match expr {
1901 Expr::$variant(inner) => return Ok(inner),
1902 Expr::Group(next) => expr = *next.expr,
1903 _ => return Err(Error::new_spanned(expr, $msg)),
1904 }
1905 }
1906 }
1907 }
1908 )*
1909 };
1910 }
1911
1912 impl_by_parsing_expr! {
1913 ExprBox, Box, "expected box expression",
1914 ExprArray, Array, "expected slice literal expression",
1915 ExprCall, Call, "expected function call expression",
1916 ExprMethodCall, MethodCall, "expected method call expression",
1917 ExprTuple, Tuple, "expected tuple expression",
1918 ExprBinary, Binary, "expected binary operation",
1919 ExprUnary, Unary, "expected unary operation",
1920 ExprCast, Cast, "expected cast expression",
1921 ExprType, Type, "expected type ascription expression",
1922 ExprLet, Let, "expected let guard",
1923 ExprClosure, Closure, "expected closure expression",
1924 ExprUnsafe, Unsafe, "expected unsafe block",
1925 ExprBlock, Block, "expected blocked scope",
1926 ExprAssign, Assign, "expected assignment expression",
1927 ExprAssignOp, AssignOp, "expected compound assignment expression",
1928 ExprField, Field, "expected struct field access",
1929 ExprIndex, Index, "expected indexing expression",
1930 ExprRange, Range, "expected range expression",
1931 ExprReference, Reference, "expected referencing operation",
1932 ExprBreak, Break, "expected break expression",
1933 ExprContinue, Continue, "expected continue expression",
1934 ExprReturn, Return, "expected return expression",
1935 ExprMacro, Macro, "expected macro invocation expression",
1936 ExprStruct, Struct, "expected struct literal expression",
1937 ExprRepeat, Repeat, "expected array literal constructed from one repeated element",
1938 ExprParen, Paren, "expected parenthesized expression",
1939 ExprTry, Try, "expected try expression",
1940 ExprAsync, Async, "expected async block",
1941 ExprTryBlock, TryBlock, "expected try block",
1942 ExprYield, Yield, "expected yield expression",
1943 }
1944
1945 #[cfg(feature = "full")]
expr_try_block(input: ParseStream) -> Result<ExprTryBlock>1946 fn expr_try_block(input: ParseStream) -> Result<ExprTryBlock> {
1947 Ok(ExprTryBlock {
1948 attrs: Vec::new(),
1949 try_token: input.parse()?,
1950 block: input.parse()?,
1951 })
1952 }
1953
1954 #[cfg(feature = "full")]
expr_yield(input: ParseStream) -> Result<ExprYield>1955 fn expr_yield(input: ParseStream) -> Result<ExprYield> {
1956 Ok(ExprYield {
1957 attrs: Vec::new(),
1958 yield_token: input.parse()?,
1959 expr: {
1960 if !input.is_empty() && !input.peek(Token![,]) && !input.peek(Token![;]) {
1961 Some(input.parse()?)
1962 } else {
1963 None
1964 }
1965 },
1966 })
1967 }
1968
1969 #[cfg(feature = "full")]
expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure>1970 fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
1971 let asyncness: Option<Token![async]> = input.parse()?;
1972 let movability: Option<Token![static]> = if asyncness.is_none() {
1973 input.parse()?
1974 } else {
1975 None
1976 };
1977 let capture: Option<Token![move]> = input.parse()?;
1978 let or1_token: Token![|] = input.parse()?;
1979
1980 let mut inputs = Punctuated::new();
1981 loop {
1982 if input.peek(Token![|]) {
1983 break;
1984 }
1985 let value = fn_arg(input)?;
1986 inputs.push_value(value);
1987 if input.peek(Token![|]) {
1988 break;
1989 }
1990 let punct: Token![,] = input.parse()?;
1991 inputs.push_punct(punct);
1992 }
1993
1994 let or2_token: Token![|] = input.parse()?;
1995
1996 let (output, body) = if input.peek(Token![->]) {
1997 let arrow_token: Token![->] = input.parse()?;
1998 let ty: Type = input.parse()?;
1999 let body: Block = input.parse()?;
2000 let output = ReturnType::Type(arrow_token, Box::new(ty));
2001 let block = Expr::Block(ExprBlock {
2002 attrs: Vec::new(),
2003 label: None,
2004 block: body,
2005 });
2006 (output, block)
2007 } else {
2008 let body = ambiguous_expr(input, allow_struct)?;
2009 (ReturnType::Default, body)
2010 };
2011
2012 Ok(ExprClosure {
2013 attrs: Vec::new(),
2014 asyncness: asyncness,
2015 movability: movability,
2016 capture: capture,
2017 or1_token: or1_token,
2018 inputs: inputs,
2019 or2_token: or2_token,
2020 output: output,
2021 body: Box::new(body),
2022 })
2023 }
2024
2025 #[cfg(feature = "full")]
expr_async(input: ParseStream) -> Result<ExprAsync>2026 fn expr_async(input: ParseStream) -> Result<ExprAsync> {
2027 Ok(ExprAsync {
2028 attrs: Vec::new(),
2029 async_token: input.parse()?,
2030 capture: input.parse()?,
2031 block: input.parse()?,
2032 })
2033 }
2034
2035 #[cfg(feature = "full")]
fn_arg(input: ParseStream) -> Result<FnArg>2036 fn fn_arg(input: ParseStream) -> Result<FnArg> {
2037 let pat: Pat = input.parse()?;
2038
2039 if input.peek(Token![:]) {
2040 Ok(FnArg::Captured(ArgCaptured {
2041 pat: pat,
2042 colon_token: input.parse()?,
2043 ty: input.parse()?,
2044 }))
2045 } else {
2046 Ok(FnArg::Inferred(pat))
2047 }
2048 }
2049
2050 #[cfg(feature = "full")]
2051 impl Parse for ExprWhile {
parse(input: ParseStream) -> Result<Self>2052 fn parse(input: ParseStream) -> Result<Self> {
2053 let label: Option<Label> = input.parse()?;
2054 let while_token: Token![while] = input.parse()?;
2055 let cond = expr_no_struct(input)?;
2056
2057 let content;
2058 let brace_token = braced!(content in input);
2059 let inner_attrs = content.call(Attribute::parse_inner)?;
2060 let stmts = content.call(Block::parse_within)?;
2061
2062 Ok(ExprWhile {
2063 attrs: inner_attrs,
2064 label: label,
2065 while_token: while_token,
2066 cond: Box::new(cond),
2067 body: Block {
2068 brace_token: brace_token,
2069 stmts: stmts,
2070 },
2071 })
2072 }
2073 }
2074
2075 #[cfg(feature = "full")]
2076 impl Parse for Label {
parse(input: ParseStream) -> Result<Self>2077 fn parse(input: ParseStream) -> Result<Self> {
2078 Ok(Label {
2079 name: input.parse()?,
2080 colon_token: input.parse()?,
2081 })
2082 }
2083 }
2084
2085 #[cfg(feature = "full")]
2086 impl Parse for Option<Label> {
parse(input: ParseStream) -> Result<Self>2087 fn parse(input: ParseStream) -> Result<Self> {
2088 if input.peek(Lifetime) {
2089 input.parse().map(Some)
2090 } else {
2091 Ok(None)
2092 }
2093 }
2094 }
2095
2096 #[cfg(feature = "full")]
expr_continue(input: ParseStream) -> Result<ExprContinue>2097 fn expr_continue(input: ParseStream) -> Result<ExprContinue> {
2098 Ok(ExprContinue {
2099 attrs: Vec::new(),
2100 continue_token: input.parse()?,
2101 label: input.parse()?,
2102 })
2103 }
2104
2105 #[cfg(feature = "full")]
expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak>2106 fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
2107 Ok(ExprBreak {
2108 attrs: Vec::new(),
2109 break_token: input.parse()?,
2110 label: input.parse()?,
2111 expr: {
2112 if input.is_empty()
2113 || input.peek(Token![,])
2114 || input.peek(Token![;])
2115 || !allow_struct.0 && input.peek(token::Brace)
2116 {
2117 None
2118 } else {
2119 let expr = ambiguous_expr(input, allow_struct)?;
2120 Some(Box::new(expr))
2121 }
2122 },
2123 })
2124 }
2125
2126 #[cfg(feature = "full")]
expr_ret(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn>2127 fn expr_ret(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn> {
2128 Ok(ExprReturn {
2129 attrs: Vec::new(),
2130 return_token: input.parse()?,
2131 expr: {
2132 if input.is_empty() || input.peek(Token![,]) || input.peek(Token![;]) {
2133 None
2134 } else {
2135 // NOTE: return is greedy and eats blocks after it even when in a
2136 // position where structs are not allowed, such as in if statement
2137 // conditions. For example:
2138 //
2139 // if return { println!("A") } {} // Prints "A"
2140 let expr = ambiguous_expr(input, allow_struct)?;
2141 Some(Box::new(expr))
2142 }
2143 },
2144 })
2145 }
2146
2147 #[cfg(feature = "full")]
2148 impl Parse for FieldValue {
parse(input: ParseStream) -> Result<Self>2149 fn parse(input: ParseStream) -> Result<Self> {
2150 let member: Member = input.parse()?;
2151 let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() {
2152 let colon_token: Token![:] = input.parse()?;
2153 let value: Expr = input.parse()?;
2154 (Some(colon_token), value)
2155 } else if let Member::Named(ref ident) = member {
2156 let value = Expr::Path(ExprPath {
2157 attrs: Vec::new(),
2158 qself: None,
2159 path: Path::from(ident.clone()),
2160 });
2161 (None, value)
2162 } else {
2163 unreachable!()
2164 };
2165
2166 Ok(FieldValue {
2167 attrs: Vec::new(),
2168 member: member,
2169 colon_token: colon_token,
2170 expr: value,
2171 })
2172 }
2173 }
2174
2175 #[cfg(feature = "full")]
expr_struct_helper( input: ParseStream, outer_attrs: Vec<Attribute>, path: Path, ) -> Result<ExprStruct>2176 fn expr_struct_helper(
2177 input: ParseStream,
2178 outer_attrs: Vec<Attribute>,
2179 path: Path,
2180 ) -> Result<ExprStruct> {
2181 let content;
2182 let brace_token = braced!(content in input);
2183 let inner_attrs = content.call(Attribute::parse_inner)?;
2184
2185 let mut fields = Punctuated::new();
2186 loop {
2187 let attrs = content.call(Attribute::parse_outer)?;
2188 if content.fork().parse::<Member>().is_err() {
2189 if attrs.is_empty() {
2190 break;
2191 } else {
2192 return Err(content.error("expected struct field"));
2193 }
2194 }
2195
2196 fields.push(FieldValue {
2197 attrs: attrs,
2198 ..content.parse()?
2199 });
2200
2201 if !content.peek(Token![,]) {
2202 break;
2203 }
2204 let punct: Token![,] = content.parse()?;
2205 fields.push_punct(punct);
2206 }
2207
2208 let (dot2_token, rest) = if fields.empty_or_trailing() && content.peek(Token![..]) {
2209 let dot2_token: Token![..] = content.parse()?;
2210 let rest: Expr = content.parse()?;
2211 (Some(dot2_token), Some(Box::new(rest)))
2212 } else {
2213 (None, None)
2214 };
2215
2216 Ok(ExprStruct {
2217 attrs: private::attrs(outer_attrs, inner_attrs),
2218 brace_token: brace_token,
2219 path: path,
2220 fields: fields,
2221 dot2_token: dot2_token,
2222 rest: rest,
2223 })
2224 }
2225
2226 #[cfg(feature = "full")]
expr_unsafe(input: ParseStream) -> Result<ExprUnsafe>2227 fn expr_unsafe(input: ParseStream) -> Result<ExprUnsafe> {
2228 let unsafe_token: Token![unsafe] = input.parse()?;
2229
2230 let content;
2231 let brace_token = braced!(content in input);
2232 let inner_attrs = content.call(Attribute::parse_inner)?;
2233 let stmts = content.call(Block::parse_within)?;
2234
2235 Ok(ExprUnsafe {
2236 attrs: inner_attrs,
2237 unsafe_token: unsafe_token,
2238 block: Block {
2239 brace_token: brace_token,
2240 stmts: stmts,
2241 },
2242 })
2243 }
2244
2245 #[cfg(feature = "full")]
expr_block(input: ParseStream) -> Result<ExprBlock>2246 pub fn expr_block(input: ParseStream) -> Result<ExprBlock> {
2247 let label: Option<Label> = input.parse()?;
2248
2249 let content;
2250 let brace_token = braced!(content in input);
2251 let inner_attrs = content.call(Attribute::parse_inner)?;
2252 let stmts = content.call(Block::parse_within)?;
2253
2254 Ok(ExprBlock {
2255 attrs: inner_attrs,
2256 label: label,
2257 block: Block {
2258 brace_token: brace_token,
2259 stmts: stmts,
2260 },
2261 })
2262 }
2263
2264 #[cfg(feature = "full")]
expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange>2265 fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
2266 Ok(ExprRange {
2267 attrs: Vec::new(),
2268 from: None,
2269 limits: input.parse()?,
2270 to: {
2271 if input.is_empty()
2272 || input.peek(Token![,])
2273 || input.peek(Token![;])
2274 || !allow_struct.0 && input.peek(token::Brace)
2275 {
2276 None
2277 } else {
2278 let to = ambiguous_expr(input, allow_struct)?;
2279 Some(Box::new(to))
2280 }
2281 },
2282 })
2283 }
2284
2285 #[cfg(feature = "full")]
2286 impl Parse for RangeLimits {
parse(input: ParseStream) -> Result<Self>2287 fn parse(input: ParseStream) -> Result<Self> {
2288 let lookahead = input.lookahead1();
2289 if lookahead.peek(Token![..=]) {
2290 input.parse().map(RangeLimits::Closed)
2291 } else if lookahead.peek(Token![...]) {
2292 let dot3: Token![...] = input.parse()?;
2293 Ok(RangeLimits::Closed(Token![..=](dot3.spans)))
2294 } else if lookahead.peek(Token![..]) {
2295 input.parse().map(RangeLimits::HalfOpen)
2296 } else {
2297 Err(lookahead.error())
2298 }
2299 }
2300 }
2301
2302 impl Parse for ExprPath {
parse(input: ParseStream) -> Result<Self>2303 fn parse(input: ParseStream) -> Result<Self> {
2304 #[cfg(not(feature = "full"))]
2305 let attrs = Vec::new();
2306 #[cfg(feature = "full")]
2307 let attrs = input.call(Attribute::parse_outer)?;
2308
2309 let (qself, path) = path::parsing::qpath(input, true)?;
2310
2311 Ok(ExprPath {
2312 attrs: attrs,
2313 qself: qself,
2314 path: path,
2315 })
2316 }
2317 }
2318
2319 #[cfg(feature = "full")]
2320 impl Parse for Block {
parse(input: ParseStream) -> Result<Self>2321 fn parse(input: ParseStream) -> Result<Self> {
2322 let content;
2323 Ok(Block {
2324 brace_token: braced!(content in input),
2325 stmts: content.call(Block::parse_within)?,
2326 })
2327 }
2328 }
2329
2330 #[cfg(feature = "full")]
2331 impl Block {
2332 /// Parse the body of a block as zero or more statements, possibly
2333 /// including one trailing expression.
2334 ///
2335 /// *This function is available if Syn is built with the `"parsing"`
2336 /// feature.*
2337 ///
2338 /// # Example
2339 ///
2340 /// ```edition2018
2341 /// use syn::{braced, token, Attribute, Block, Ident, Result, Stmt, Token};
2342 /// use syn::parse::{Parse, ParseStream};
2343 ///
2344 /// // Parse a function with no generics or parameter list.
2345 /// //
2346 /// // fn playground {
2347 /// // let mut x = 1;
2348 /// // x += 1;
2349 /// // println!("{}", x);
2350 /// // }
2351 /// struct MiniFunction {
2352 /// attrs: Vec<Attribute>,
2353 /// fn_token: Token![fn],
2354 /// name: Ident,
2355 /// brace_token: token::Brace,
2356 /// stmts: Vec<Stmt>,
2357 /// }
2358 ///
2359 /// impl Parse for MiniFunction {
2360 /// fn parse(input: ParseStream) -> Result<Self> {
2361 /// let outer_attrs = input.call(Attribute::parse_outer)?;
2362 /// let fn_token: Token![fn] = input.parse()?;
2363 /// let name: Ident = input.parse()?;
2364 ///
2365 /// let content;
2366 /// let brace_token = braced!(content in input);
2367 /// let inner_attrs = content.call(Attribute::parse_inner)?;
2368 /// let stmts = content.call(Block::parse_within)?;
2369 ///
2370 /// Ok(MiniFunction {
2371 /// attrs: {
2372 /// let mut attrs = outer_attrs;
2373 /// attrs.extend(inner_attrs);
2374 /// attrs
2375 /// },
2376 /// fn_token: fn_token,
2377 /// name: name,
2378 /// brace_token: brace_token,
2379 /// stmts: stmts,
2380 /// })
2381 /// }
2382 /// }
2383 /// ```
parse_within(input: ParseStream) -> Result<Vec<Stmt>>2384 pub fn parse_within(input: ParseStream) -> Result<Vec<Stmt>> {
2385 let mut stmts = Vec::new();
2386 loop {
2387 while input.peek(Token![;]) {
2388 input.parse::<Token![;]>()?;
2389 }
2390 if input.is_empty() {
2391 break;
2392 }
2393 let s = parse_stmt(input, true)?;
2394 let requires_semicolon = if let Stmt::Expr(ref s) = s {
2395 requires_terminator(s)
2396 } else {
2397 false
2398 };
2399 stmts.push(s);
2400 if input.is_empty() {
2401 break;
2402 } else if requires_semicolon {
2403 return Err(input.error("unexpected token"));
2404 }
2405 }
2406 Ok(stmts)
2407 }
2408 }
2409
2410 #[cfg(feature = "full")]
2411 impl Parse for Stmt {
parse(input: ParseStream) -> Result<Self>2412 fn parse(input: ParseStream) -> Result<Self> {
2413 parse_stmt(input, false)
2414 }
2415 }
2416
2417 #[cfg(feature = "full")]
parse_stmt(input: ParseStream, allow_nosemi: bool) -> Result<Stmt>2418 fn parse_stmt(input: ParseStream, allow_nosemi: bool) -> Result<Stmt> {
2419 let ahead = input.fork();
2420 ahead.call(Attribute::parse_outer)?;
2421
2422 if {
2423 let ahead = ahead.fork();
2424 // Only parse braces here; paren and bracket will get parsed as
2425 // expression statements
2426 ahead.call(Path::parse_mod_style).is_ok()
2427 && ahead.parse::<Token![!]>().is_ok()
2428 && (ahead.peek(token::Brace) || ahead.peek(Ident))
2429 } {
2430 stmt_mac(input)
2431 } else if ahead.peek(Token![let]) {
2432 stmt_local(input).map(Stmt::Local)
2433 } else if ahead.peek(Token![pub])
2434 || ahead.peek(Token![crate]) && !ahead.peek2(Token![::])
2435 || ahead.peek(Token![extern]) && !ahead.peek2(Token![::])
2436 || ahead.peek(Token![use])
2437 || ahead.peek(Token![static]) && (ahead.peek2(Token![mut]) || ahead.peek2(Ident))
2438 || ahead.peek(Token![const])
2439 || ahead.peek(Token![unsafe]) && !ahead.peek2(token::Brace)
2440 || ahead.peek(Token![async]) && (ahead.peek2(Token![extern]) || ahead.peek2(Token![fn]))
2441 || ahead.peek(Token![fn])
2442 || ahead.peek(Token![mod])
2443 || ahead.peek(Token![type])
2444 || ahead.peek(Token![existential]) && ahead.peek2(Token![type])
2445 || ahead.peek(Token![struct])
2446 || ahead.peek(Token![enum])
2447 || ahead.peek(Token![union]) && ahead.peek2(Ident)
2448 || ahead.peek(Token![auto]) && ahead.peek2(Token![trait])
2449 || ahead.peek(Token![trait])
2450 || ahead.peek(Token![default])
2451 && (ahead.peek2(Token![unsafe]) || ahead.peek2(Token![impl]))
2452 || ahead.peek(Token![impl])
2453 || ahead.peek(Token![macro])
2454 {
2455 input.parse().map(Stmt::Item)
2456 } else {
2457 stmt_expr(input, allow_nosemi)
2458 }
2459 }
2460
2461 #[cfg(feature = "full")]
stmt_mac(input: ParseStream) -> Result<Stmt>2462 fn stmt_mac(input: ParseStream) -> Result<Stmt> {
2463 let attrs = input.call(Attribute::parse_outer)?;
2464 let path = input.call(Path::parse_mod_style)?;
2465 let bang_token: Token![!] = input.parse()?;
2466 let ident: Option<Ident> = input.parse()?;
2467 let (delimiter, tts) = mac::parse_delimiter(input)?;
2468 let semi_token: Option<Token![;]> = input.parse()?;
2469
2470 Ok(Stmt::Item(Item::Macro(ItemMacro {
2471 attrs: attrs,
2472 ident: ident,
2473 mac: Macro {
2474 path: path,
2475 bang_token: bang_token,
2476 delimiter: delimiter,
2477 tts: tts,
2478 },
2479 semi_token: semi_token,
2480 })))
2481 }
2482
2483 #[cfg(feature = "full")]
stmt_local(input: ParseStream) -> Result<Local>2484 fn stmt_local(input: ParseStream) -> Result<Local> {
2485 Ok(Local {
2486 attrs: input.call(Attribute::parse_outer)?,
2487 let_token: input.parse()?,
2488 pats: {
2489 let mut pats = Punctuated::new();
2490 let value: Pat = input.parse()?;
2491 pats.push_value(value);
2492 while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
2493 let punct = input.parse()?;
2494 pats.push_punct(punct);
2495 let value: Pat = input.parse()?;
2496 pats.push_value(value);
2497 }
2498 pats
2499 },
2500 ty: {
2501 if input.peek(Token![:]) {
2502 let colon_token: Token![:] = input.parse()?;
2503 let ty: Type = input.parse()?;
2504 Some((colon_token, Box::new(ty)))
2505 } else {
2506 None
2507 }
2508 },
2509 init: {
2510 if input.peek(Token![=]) {
2511 let eq_token: Token![=] = input.parse()?;
2512 let init: Expr = input.parse()?;
2513 Some((eq_token, Box::new(init)))
2514 } else {
2515 None
2516 }
2517 },
2518 semi_token: input.parse()?,
2519 })
2520 }
2521
2522 #[cfg(feature = "full")]
stmt_expr(input: ParseStream, allow_nosemi: bool) -> Result<Stmt>2523 fn stmt_expr(input: ParseStream, allow_nosemi: bool) -> Result<Stmt> {
2524 let mut attrs = input.call(Attribute::parse_outer)?;
2525 let mut e = expr_early(input)?;
2526
2527 attrs.extend(e.replace_attrs(Vec::new()));
2528 e.replace_attrs(attrs);
2529
2530 if input.peek(Token![;]) {
2531 return Ok(Stmt::Semi(e, input.parse()?));
2532 }
2533
2534 if allow_nosemi || !requires_terminator(&e) {
2535 Ok(Stmt::Expr(e))
2536 } else {
2537 Err(input.error("expected semicolon"))
2538 }
2539 }
2540
2541 #[cfg(feature = "full")]
2542 impl Parse for Pat {
parse(input: ParseStream) -> Result<Self>2543 fn parse(input: ParseStream) -> Result<Self> {
2544 let lookahead = input.lookahead1();
2545 if lookahead.peek(Token![_]) {
2546 input.call(pat_wild).map(Pat::Wild)
2547 } else if lookahead.peek(Token![box]) {
2548 input.call(pat_box).map(Pat::Box)
2549 } else if lookahead.peek(Token![-]) || lookahead.peek(Lit) {
2550 pat_lit_or_range(input)
2551 } else if input.peek(Ident)
2552 && ({
2553 input.peek2(Token![::])
2554 || input.peek2(Token![!])
2555 || input.peek2(token::Brace)
2556 || input.peek2(token::Paren)
2557 || input.peek2(Token![..])
2558 && !{
2559 let ahead = input.fork();
2560 ahead.parse::<Ident>()?;
2561 ahead.parse::<RangeLimits>()?;
2562 ahead.is_empty() || ahead.peek(Token![,])
2563 }
2564 })
2565 || input.peek(Token![self]) && input.peek2(Token![::])
2566 || input.peek(Token![::])
2567 || input.peek(Token![<])
2568 || input.peek(Token![Self])
2569 || input.peek(Token![super])
2570 || input.peek(Token![extern])
2571 || input.peek(Token![crate])
2572 {
2573 pat_path_or_macro_or_struct_or_range(input)
2574 } else if input.peek(Token![ref])
2575 || input.peek(Token![mut])
2576 || input.peek(Token![self])
2577 || input.peek(Ident)
2578 {
2579 input.call(pat_ident).map(Pat::Ident)
2580 } else if lookahead.peek(token::Paren) {
2581 input.call(pat_tuple).map(Pat::Tuple)
2582 } else if lookahead.peek(Token![&]) {
2583 input.call(pat_ref).map(Pat::Ref)
2584 } else if lookahead.peek(token::Bracket) {
2585 input.call(pat_slice).map(Pat::Slice)
2586 } else {
2587 Err(lookahead.error())
2588 }
2589 }
2590 }
2591
2592 #[cfg(feature = "full")]
pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat>2593 fn pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat> {
2594 let (qself, path) = path::parsing::qpath(input, true)?;
2595
2596 if input.peek(Token![..]) {
2597 return pat_range(input, qself, path).map(Pat::Range);
2598 }
2599
2600 if qself.is_some() {
2601 return Ok(Pat::Path(PatPath {
2602 qself: qself,
2603 path: path,
2604 }));
2605 }
2606
2607 if input.peek(Token![!]) && !input.peek(Token![!=]) {
2608 let mut contains_arguments = false;
2609 for segment in &path.segments {
2610 match segment.arguments {
2611 PathArguments::None => {}
2612 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
2613 contains_arguments = true;
2614 }
2615 }
2616 }
2617
2618 if !contains_arguments {
2619 let bang_token: Token![!] = input.parse()?;
2620 let (delimiter, tts) = mac::parse_delimiter(input)?;
2621 return Ok(Pat::Macro(PatMacro {
2622 mac: Macro {
2623 path: path,
2624 bang_token: bang_token,
2625 delimiter: delimiter,
2626 tts: tts,
2627 },
2628 }));
2629 }
2630 }
2631
2632 if input.peek(token::Brace) {
2633 pat_struct(input, path).map(Pat::Struct)
2634 } else if input.peek(token::Paren) {
2635 pat_tuple_struct(input, path).map(Pat::TupleStruct)
2636 } else if input.peek(Token![..]) {
2637 pat_range(input, qself, path).map(Pat::Range)
2638 } else {
2639 Ok(Pat::Path(PatPath {
2640 qself: qself,
2641 path: path,
2642 }))
2643 }
2644 }
2645
2646 #[cfg(feature = "full")]
pat_wild(input: ParseStream) -> Result<PatWild>2647 fn pat_wild(input: ParseStream) -> Result<PatWild> {
2648 Ok(PatWild {
2649 underscore_token: input.parse()?,
2650 })
2651 }
2652
2653 #[cfg(feature = "full")]
pat_box(input: ParseStream) -> Result<PatBox>2654 fn pat_box(input: ParseStream) -> Result<PatBox> {
2655 Ok(PatBox {
2656 box_token: input.parse()?,
2657 pat: input.parse()?,
2658 })
2659 }
2660
2661 #[cfg(feature = "full")]
pat_ident(input: ParseStream) -> Result<PatIdent>2662 fn pat_ident(input: ParseStream) -> Result<PatIdent> {
2663 Ok(PatIdent {
2664 by_ref: input.parse()?,
2665 mutability: input.parse()?,
2666 ident: input.call(Ident::parse_any)?,
2667 subpat: {
2668 if input.peek(Token![@]) {
2669 let at_token: Token![@] = input.parse()?;
2670 let subpat: Pat = input.parse()?;
2671 Some((at_token, Box::new(subpat)))
2672 } else {
2673 None
2674 }
2675 },
2676 })
2677 }
2678
2679 #[cfg(feature = "full")]
pat_tuple_struct(input: ParseStream, path: Path) -> Result<PatTupleStruct>2680 fn pat_tuple_struct(input: ParseStream, path: Path) -> Result<PatTupleStruct> {
2681 Ok(PatTupleStruct {
2682 path: path,
2683 pat: input.call(pat_tuple)?,
2684 })
2685 }
2686
2687 #[cfg(feature = "full")]
pat_struct(input: ParseStream, path: Path) -> Result<PatStruct>2688 fn pat_struct(input: ParseStream, path: Path) -> Result<PatStruct> {
2689 let content;
2690 let brace_token = braced!(content in input);
2691
2692 let mut fields = Punctuated::new();
2693 while !content.is_empty() && !content.peek(Token![..]) {
2694 let value = content.call(field_pat)?;
2695 fields.push_value(value);
2696 if !content.peek(Token![,]) {
2697 break;
2698 }
2699 let punct: Token![,] = content.parse()?;
2700 fields.push_punct(punct);
2701 }
2702
2703 let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
2704 Some(content.parse()?)
2705 } else {
2706 None
2707 };
2708
2709 Ok(PatStruct {
2710 path: path,
2711 brace_token: brace_token,
2712 fields: fields,
2713 dot2_token: dot2_token,
2714 })
2715 }
2716
2717 #[cfg(feature = "full")]
field_pat(input: ParseStream) -> Result<FieldPat>2718 fn field_pat(input: ParseStream) -> Result<FieldPat> {
2719 let boxed: Option<Token![box]> = input.parse()?;
2720 let by_ref: Option<Token![ref]> = input.parse()?;
2721 let mutability: Option<Token![mut]> = input.parse()?;
2722 let member: Member = input.parse()?;
2723
2724 if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
2725 || member.is_unnamed()
2726 {
2727 return Ok(FieldPat {
2728 attrs: Vec::new(),
2729 member: member,
2730 colon_token: input.parse()?,
2731 pat: input.parse()?,
2732 });
2733 }
2734
2735 let ident = match member {
2736 Member::Named(ident) => ident,
2737 Member::Unnamed(_) => unreachable!(),
2738 };
2739
2740 let mut pat = Pat::Ident(PatIdent {
2741 by_ref: by_ref,
2742 mutability: mutability,
2743 ident: ident.clone(),
2744 subpat: None,
2745 });
2746
2747 if let Some(boxed) = boxed {
2748 pat = Pat::Box(PatBox {
2749 pat: Box::new(pat),
2750 box_token: boxed,
2751 });
2752 }
2753
2754 Ok(FieldPat {
2755 member: Member::Named(ident),
2756 pat: Box::new(pat),
2757 attrs: Vec::new(),
2758 colon_token: None,
2759 })
2760 }
2761
2762 impl Parse for Member {
parse(input: ParseStream) -> Result<Self>2763 fn parse(input: ParseStream) -> Result<Self> {
2764 if input.peek(Ident) {
2765 input.parse().map(Member::Named)
2766 } else if input.peek(LitInt) {
2767 input.parse().map(Member::Unnamed)
2768 } else {
2769 Err(input.error("expected identifier or integer"))
2770 }
2771 }
2772 }
2773
2774 #[cfg(feature = "full")]
2775 impl Parse for Arm {
parse(input: ParseStream) -> Result<Arm>2776 fn parse(input: ParseStream) -> Result<Arm> {
2777 let requires_comma;
2778 Ok(Arm {
2779 attrs: input.call(Attribute::parse_outer)?,
2780 leading_vert: input.parse()?,
2781 pats: {
2782 let mut pats = Punctuated::new();
2783 let value: Pat = input.parse()?;
2784 pats.push_value(value);
2785 loop {
2786 if !input.peek(Token![|]) {
2787 break;
2788 }
2789 let punct = input.parse()?;
2790 pats.push_punct(punct);
2791 let value: Pat = input.parse()?;
2792 pats.push_value(value);
2793 }
2794 pats
2795 },
2796 guard: {
2797 if input.peek(Token![if]) {
2798 let if_token: Token![if] = input.parse()?;
2799 let guard: Expr = input.parse()?;
2800 Some((if_token, Box::new(guard)))
2801 } else {
2802 None
2803 }
2804 },
2805 fat_arrow_token: input.parse()?,
2806 body: {
2807 let body = input.call(expr_early)?;
2808 requires_comma = requires_terminator(&body);
2809 Box::new(body)
2810 },
2811 comma: {
2812 if requires_comma && !input.is_empty() {
2813 Some(input.parse()?)
2814 } else {
2815 input.parse()?
2816 }
2817 },
2818 })
2819 }
2820 }
2821
2822 impl Parse for Index {
parse(input: ParseStream) -> Result<Self>2823 fn parse(input: ParseStream) -> Result<Self> {
2824 let lit: LitInt = input.parse()?;
2825 if let IntSuffix::None = lit.suffix() {
2826 Ok(Index {
2827 index: lit.value() as u32,
2828 span: lit.span(),
2829 })
2830 } else {
2831 Err(Error::new(lit.span(), "expected unsuffixed integer"))
2832 }
2833 }
2834 }
2835
2836 #[cfg(feature = "full")]
pat_range(input: ParseStream, qself: Option<QSelf>, path: Path) -> Result<PatRange>2837 fn pat_range(input: ParseStream, qself: Option<QSelf>, path: Path) -> Result<PatRange> {
2838 Ok(PatRange {
2839 lo: Box::new(Expr::Path(ExprPath {
2840 attrs: Vec::new(),
2841 qself: qself,
2842 path: path,
2843 })),
2844 limits: input.parse()?,
2845 hi: input.call(pat_lit_expr)?,
2846 })
2847 }
2848
2849 #[cfg(feature = "full")]
pat_tuple(input: ParseStream) -> Result<PatTuple>2850 fn pat_tuple(input: ParseStream) -> Result<PatTuple> {
2851 let content;
2852 let paren_token = parenthesized!(content in input);
2853
2854 let mut front = Punctuated::new();
2855 let mut dot2_token = None::<Token![..]>;
2856 let mut comma_token = None::<Token![,]>;
2857 loop {
2858 if content.is_empty() {
2859 break;
2860 }
2861 if content.peek(Token![..]) {
2862 dot2_token = Some(content.parse()?);
2863 comma_token = content.parse()?;
2864 break;
2865 }
2866 let value: Pat = content.parse()?;
2867 front.push_value(value);
2868 if content.is_empty() {
2869 break;
2870 }
2871 let punct = content.parse()?;
2872 front.push_punct(punct);
2873 }
2874
2875 let mut back = Punctuated::new();
2876 while !content.is_empty() {
2877 let value: Pat = content.parse()?;
2878 back.push_value(value);
2879 if content.is_empty() {
2880 break;
2881 }
2882 let punct = content.parse()?;
2883 back.push_punct(punct);
2884 }
2885
2886 Ok(PatTuple {
2887 paren_token: paren_token,
2888 front: front,
2889 dot2_token: dot2_token,
2890 comma_token: comma_token,
2891 back: back,
2892 })
2893 }
2894
2895 #[cfg(feature = "full")]
pat_ref(input: ParseStream) -> Result<PatRef>2896 fn pat_ref(input: ParseStream) -> Result<PatRef> {
2897 Ok(PatRef {
2898 and_token: input.parse()?,
2899 mutability: input.parse()?,
2900 pat: input.parse()?,
2901 })
2902 }
2903
2904 #[cfg(feature = "full")]
pat_lit_or_range(input: ParseStream) -> Result<Pat>2905 fn pat_lit_or_range(input: ParseStream) -> Result<Pat> {
2906 let lo = input.call(pat_lit_expr)?;
2907 if input.peek(Token![..]) {
2908 Ok(Pat::Range(PatRange {
2909 lo: lo,
2910 limits: input.parse()?,
2911 hi: input.call(pat_lit_expr)?,
2912 }))
2913 } else {
2914 Ok(Pat::Lit(PatLit { expr: lo }))
2915 }
2916 }
2917
2918 #[cfg(feature = "full")]
pat_lit_expr(input: ParseStream) -> Result<Box<Expr>>2919 fn pat_lit_expr(input: ParseStream) -> Result<Box<Expr>> {
2920 let neg: Option<Token![-]> = input.parse()?;
2921
2922 let lookahead = input.lookahead1();
2923 let expr = if lookahead.peek(Lit) {
2924 Expr::Lit(input.parse()?)
2925 } else if lookahead.peek(Ident)
2926 || lookahead.peek(Token![::])
2927 || lookahead.peek(Token![<])
2928 || lookahead.peek(Token![self])
2929 || lookahead.peek(Token![Self])
2930 || lookahead.peek(Token![super])
2931 || lookahead.peek(Token![extern])
2932 || lookahead.peek(Token![crate])
2933 {
2934 Expr::Path(input.parse()?)
2935 } else {
2936 return Err(lookahead.error());
2937 };
2938
2939 Ok(Box::new(if let Some(neg) = neg {
2940 Expr::Unary(ExprUnary {
2941 attrs: Vec::new(),
2942 op: UnOp::Neg(neg),
2943 expr: Box::new(expr),
2944 })
2945 } else {
2946 expr
2947 }))
2948 }
2949
2950 #[cfg(feature = "full")]
pat_slice(input: ParseStream) -> Result<PatSlice>2951 fn pat_slice(input: ParseStream) -> Result<PatSlice> {
2952 let content;
2953 let bracket_token = bracketed!(content in input);
2954
2955 let mut front = Punctuated::new();
2956 let mut middle = None;
2957 loop {
2958 if content.is_empty() || content.peek(Token![..]) {
2959 break;
2960 }
2961 let value: Pat = content.parse()?;
2962 if content.peek(Token![..]) {
2963 middle = Some(Box::new(value));
2964 break;
2965 }
2966 front.push_value(value);
2967 if content.is_empty() {
2968 break;
2969 }
2970 let punct = content.parse()?;
2971 front.push_punct(punct);
2972 }
2973
2974 let dot2_token: Option<Token![..]> = content.parse()?;
2975 let mut comma_token = None::<Token![,]>;
2976 let mut back = Punctuated::new();
2977 if dot2_token.is_some() {
2978 comma_token = content.parse()?;
2979 if comma_token.is_some() {
2980 loop {
2981 if content.is_empty() {
2982 break;
2983 }
2984 let value: Pat = content.parse()?;
2985 back.push_value(value);
2986 if content.is_empty() {
2987 break;
2988 }
2989 let punct = content.parse()?;
2990 back.push_punct(punct);
2991 }
2992 }
2993 }
2994
2995 Ok(PatSlice {
2996 bracket_token: bracket_token,
2997 front: front,
2998 middle: middle,
2999 dot2_token: dot2_token,
3000 comma_token: comma_token,
3001 back: back,
3002 })
3003 }
3004
3005 #[cfg(feature = "full")]
3006 impl Member {
is_named(&self) -> bool3007 fn is_named(&self) -> bool {
3008 match *self {
3009 Member::Named(_) => true,
3010 Member::Unnamed(_) => false,
3011 }
3012 }
3013
is_unnamed(&self) -> bool3014 fn is_unnamed(&self) -> bool {
3015 match *self {
3016 Member::Named(_) => false,
3017 Member::Unnamed(_) => true,
3018 }
3019 }
3020 }
3021 }
3022
3023 #[cfg(feature = "printing")]
3024 mod printing {
3025 use super::*;
3026
3027 use proc_macro2::{Literal, TokenStream};
3028 use quote::{ToTokens, TokenStreamExt};
3029
3030 #[cfg(feature = "full")]
3031 use attr::FilterAttrs;
3032 #[cfg(feature = "full")]
3033 use print::TokensOrDefault;
3034
3035 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
3036 // before appending it to `TokenStream`.
3037 #[cfg(feature = "full")]
wrap_bare_struct(tokens: &mut TokenStream, e: &Expr)3038 fn wrap_bare_struct(tokens: &mut TokenStream, e: &Expr) {
3039 if let Expr::Struct(_) = *e {
3040 token::Paren::default().surround(tokens, |tokens| {
3041 e.to_tokens(tokens);
3042 });
3043 } else {
3044 e.to_tokens(tokens);
3045 }
3046 }
3047
3048 #[cfg(feature = "full")]
outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream)3049 fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
3050 tokens.append_all(attrs.outer());
3051 }
3052
3053 #[cfg(feature = "full")]
inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream)3054 fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
3055 tokens.append_all(attrs.inner());
3056 }
3057
3058 #[cfg(not(feature = "full"))]
outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream)3059 fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
3060
3061 #[cfg(not(feature = "full"))]
inner_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream)3062 fn inner_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
3063
3064 #[cfg(feature = "full")]
3065 impl ToTokens for ExprBox {
to_tokens(&self, tokens: &mut TokenStream)3066 fn to_tokens(&self, tokens: &mut TokenStream) {
3067 outer_attrs_to_tokens(&self.attrs, tokens);
3068 self.box_token.to_tokens(tokens);
3069 self.expr.to_tokens(tokens);
3070 }
3071 }
3072
3073 #[cfg(feature = "full")]
3074 impl ToTokens for ExprInPlace {
to_tokens(&self, tokens: &mut TokenStream)3075 fn to_tokens(&self, tokens: &mut TokenStream) {
3076 outer_attrs_to_tokens(&self.attrs, tokens);
3077 self.place.to_tokens(tokens);
3078 self.arrow_token.to_tokens(tokens);
3079 self.value.to_tokens(tokens);
3080 }
3081 }
3082
3083 #[cfg(feature = "full")]
3084 impl ToTokens for ExprArray {
to_tokens(&self, tokens: &mut TokenStream)3085 fn to_tokens(&self, tokens: &mut TokenStream) {
3086 outer_attrs_to_tokens(&self.attrs, tokens);
3087 self.bracket_token.surround(tokens, |tokens| {
3088 inner_attrs_to_tokens(&self.attrs, tokens);
3089 self.elems.to_tokens(tokens);
3090 })
3091 }
3092 }
3093
3094 impl ToTokens for ExprCall {
to_tokens(&self, tokens: &mut TokenStream)3095 fn to_tokens(&self, tokens: &mut TokenStream) {
3096 outer_attrs_to_tokens(&self.attrs, tokens);
3097 self.func.to_tokens(tokens);
3098 self.paren_token.surround(tokens, |tokens| {
3099 self.args.to_tokens(tokens);
3100 })
3101 }
3102 }
3103
3104 #[cfg(feature = "full")]
3105 impl ToTokens for ExprMethodCall {
to_tokens(&self, tokens: &mut TokenStream)3106 fn to_tokens(&self, tokens: &mut TokenStream) {
3107 outer_attrs_to_tokens(&self.attrs, tokens);
3108 self.receiver.to_tokens(tokens);
3109 self.dot_token.to_tokens(tokens);
3110 self.method.to_tokens(tokens);
3111 self.turbofish.to_tokens(tokens);
3112 self.paren_token.surround(tokens, |tokens| {
3113 self.args.to_tokens(tokens);
3114 });
3115 }
3116 }
3117
3118 #[cfg(feature = "full")]
3119 impl ToTokens for MethodTurbofish {
to_tokens(&self, tokens: &mut TokenStream)3120 fn to_tokens(&self, tokens: &mut TokenStream) {
3121 self.colon2_token.to_tokens(tokens);
3122 self.lt_token.to_tokens(tokens);
3123 self.args.to_tokens(tokens);
3124 self.gt_token.to_tokens(tokens);
3125 }
3126 }
3127
3128 #[cfg(feature = "full")]
3129 impl ToTokens for GenericMethodArgument {
to_tokens(&self, tokens: &mut TokenStream)3130 fn to_tokens(&self, tokens: &mut TokenStream) {
3131 match *self {
3132 GenericMethodArgument::Type(ref t) => t.to_tokens(tokens),
3133 GenericMethodArgument::Const(ref c) => c.to_tokens(tokens),
3134 }
3135 }
3136 }
3137
3138 #[cfg(feature = "full")]
3139 impl ToTokens for ExprTuple {
to_tokens(&self, tokens: &mut TokenStream)3140 fn to_tokens(&self, tokens: &mut TokenStream) {
3141 outer_attrs_to_tokens(&self.attrs, tokens);
3142 self.paren_token.surround(tokens, |tokens| {
3143 inner_attrs_to_tokens(&self.attrs, tokens);
3144 self.elems.to_tokens(tokens);
3145 // If we only have one argument, we need a trailing comma to
3146 // distinguish ExprTuple from ExprParen.
3147 if self.elems.len() == 1 && !self.elems.trailing_punct() {
3148 <Token![,]>::default().to_tokens(tokens);
3149 }
3150 })
3151 }
3152 }
3153
3154 impl ToTokens for ExprBinary {
to_tokens(&self, tokens: &mut TokenStream)3155 fn to_tokens(&self, tokens: &mut TokenStream) {
3156 outer_attrs_to_tokens(&self.attrs, tokens);
3157 self.left.to_tokens(tokens);
3158 self.op.to_tokens(tokens);
3159 self.right.to_tokens(tokens);
3160 }
3161 }
3162
3163 impl ToTokens for ExprUnary {
to_tokens(&self, tokens: &mut TokenStream)3164 fn to_tokens(&self, tokens: &mut TokenStream) {
3165 outer_attrs_to_tokens(&self.attrs, tokens);
3166 self.op.to_tokens(tokens);
3167 self.expr.to_tokens(tokens);
3168 }
3169 }
3170
3171 impl ToTokens for ExprLit {
to_tokens(&self, tokens: &mut TokenStream)3172 fn to_tokens(&self, tokens: &mut TokenStream) {
3173 outer_attrs_to_tokens(&self.attrs, tokens);
3174 self.lit.to_tokens(tokens);
3175 }
3176 }
3177
3178 impl ToTokens for ExprCast {
to_tokens(&self, tokens: &mut TokenStream)3179 fn to_tokens(&self, tokens: &mut TokenStream) {
3180 outer_attrs_to_tokens(&self.attrs, tokens);
3181 self.expr.to_tokens(tokens);
3182 self.as_token.to_tokens(tokens);
3183 self.ty.to_tokens(tokens);
3184 }
3185 }
3186
3187 #[cfg(feature = "full")]
3188 impl ToTokens for ExprType {
to_tokens(&self, tokens: &mut TokenStream)3189 fn to_tokens(&self, tokens: &mut TokenStream) {
3190 outer_attrs_to_tokens(&self.attrs, tokens);
3191 self.expr.to_tokens(tokens);
3192 self.colon_token.to_tokens(tokens);
3193 self.ty.to_tokens(tokens);
3194 }
3195 }
3196
3197 #[cfg(feature = "full")]
maybe_wrap_else(tokens: &mut TokenStream, else_: &Option<(Token![else], Box<Expr>)>)3198 fn maybe_wrap_else(tokens: &mut TokenStream, else_: &Option<(Token![else], Box<Expr>)>) {
3199 if let Some((ref else_token, ref else_)) = *else_ {
3200 else_token.to_tokens(tokens);
3201
3202 // If we are not one of the valid expressions to exist in an else
3203 // clause, wrap ourselves in a block.
3204 match **else_ {
3205 Expr::If(_) | Expr::Block(_) => {
3206 else_.to_tokens(tokens);
3207 }
3208 _ => {
3209 token::Brace::default().surround(tokens, |tokens| {
3210 else_.to_tokens(tokens);
3211 });
3212 }
3213 }
3214 }
3215 }
3216
3217 #[cfg(feature = "full")]
3218 impl ToTokens for ExprLet {
to_tokens(&self, tokens: &mut TokenStream)3219 fn to_tokens(&self, tokens: &mut TokenStream) {
3220 outer_attrs_to_tokens(&self.attrs, tokens);
3221 self.let_token.to_tokens(tokens);
3222 self.pats.to_tokens(tokens);
3223 self.eq_token.to_tokens(tokens);
3224 wrap_bare_struct(tokens, &self.expr);
3225 }
3226 }
3227
3228 #[cfg(feature = "full")]
3229 impl ToTokens for ExprIf {
to_tokens(&self, tokens: &mut TokenStream)3230 fn to_tokens(&self, tokens: &mut TokenStream) {
3231 outer_attrs_to_tokens(&self.attrs, tokens);
3232 self.if_token.to_tokens(tokens);
3233 wrap_bare_struct(tokens, &self.cond);
3234 self.then_branch.to_tokens(tokens);
3235 maybe_wrap_else(tokens, &self.else_branch);
3236 }
3237 }
3238
3239 #[cfg(feature = "full")]
3240 impl ToTokens for ExprWhile {
to_tokens(&self, tokens: &mut TokenStream)3241 fn to_tokens(&self, tokens: &mut TokenStream) {
3242 outer_attrs_to_tokens(&self.attrs, tokens);
3243 self.label.to_tokens(tokens);
3244 self.while_token.to_tokens(tokens);
3245 wrap_bare_struct(tokens, &self.cond);
3246 self.body.brace_token.surround(tokens, |tokens| {
3247 inner_attrs_to_tokens(&self.attrs, tokens);
3248 tokens.append_all(&self.body.stmts);
3249 });
3250 }
3251 }
3252
3253 #[cfg(feature = "full")]
3254 impl ToTokens for ExprForLoop {
to_tokens(&self, tokens: &mut TokenStream)3255 fn to_tokens(&self, tokens: &mut TokenStream) {
3256 outer_attrs_to_tokens(&self.attrs, tokens);
3257 self.label.to_tokens(tokens);
3258 self.for_token.to_tokens(tokens);
3259 self.pat.to_tokens(tokens);
3260 self.in_token.to_tokens(tokens);
3261 wrap_bare_struct(tokens, &self.expr);
3262 self.body.brace_token.surround(tokens, |tokens| {
3263 inner_attrs_to_tokens(&self.attrs, tokens);
3264 tokens.append_all(&self.body.stmts);
3265 });
3266 }
3267 }
3268
3269 #[cfg(feature = "full")]
3270 impl ToTokens for ExprLoop {
to_tokens(&self, tokens: &mut TokenStream)3271 fn to_tokens(&self, tokens: &mut TokenStream) {
3272 outer_attrs_to_tokens(&self.attrs, tokens);
3273 self.label.to_tokens(tokens);
3274 self.loop_token.to_tokens(tokens);
3275 self.body.brace_token.surround(tokens, |tokens| {
3276 inner_attrs_to_tokens(&self.attrs, tokens);
3277 tokens.append_all(&self.body.stmts);
3278 });
3279 }
3280 }
3281
3282 #[cfg(feature = "full")]
3283 impl ToTokens for ExprMatch {
to_tokens(&self, tokens: &mut TokenStream)3284 fn to_tokens(&self, tokens: &mut TokenStream) {
3285 outer_attrs_to_tokens(&self.attrs, tokens);
3286 self.match_token.to_tokens(tokens);
3287 wrap_bare_struct(tokens, &self.expr);
3288 self.brace_token.surround(tokens, |tokens| {
3289 inner_attrs_to_tokens(&self.attrs, tokens);
3290 for (i, arm) in self.arms.iter().enumerate() {
3291 arm.to_tokens(tokens);
3292 // Ensure that we have a comma after a non-block arm, except
3293 // for the last one.
3294 let is_last = i == self.arms.len() - 1;
3295 if !is_last && requires_terminator(&arm.body) && arm.comma.is_none() {
3296 <Token![,]>::default().to_tokens(tokens);
3297 }
3298 }
3299 });
3300 }
3301 }
3302
3303 #[cfg(feature = "full")]
3304 impl ToTokens for ExprAsync {
to_tokens(&self, tokens: &mut TokenStream)3305 fn to_tokens(&self, tokens: &mut TokenStream) {
3306 outer_attrs_to_tokens(&self.attrs, tokens);
3307 self.async_token.to_tokens(tokens);
3308 self.capture.to_tokens(tokens);
3309 self.block.to_tokens(tokens);
3310 }
3311 }
3312
3313 #[cfg(feature = "full")]
3314 impl ToTokens for ExprTryBlock {
to_tokens(&self, tokens: &mut TokenStream)3315 fn to_tokens(&self, tokens: &mut TokenStream) {
3316 outer_attrs_to_tokens(&self.attrs, tokens);
3317 self.try_token.to_tokens(tokens);
3318 self.block.to_tokens(tokens);
3319 }
3320 }
3321
3322 #[cfg(feature = "full")]
3323 impl ToTokens for ExprYield {
to_tokens(&self, tokens: &mut TokenStream)3324 fn to_tokens(&self, tokens: &mut TokenStream) {
3325 outer_attrs_to_tokens(&self.attrs, tokens);
3326 self.yield_token.to_tokens(tokens);
3327 self.expr.to_tokens(tokens);
3328 }
3329 }
3330
3331 #[cfg(feature = "full")]
3332 impl ToTokens for ExprClosure {
to_tokens(&self, tokens: &mut TokenStream)3333 fn to_tokens(&self, tokens: &mut TokenStream) {
3334 outer_attrs_to_tokens(&self.attrs, tokens);
3335 self.asyncness.to_tokens(tokens);
3336 self.movability.to_tokens(tokens);
3337 self.capture.to_tokens(tokens);
3338 self.or1_token.to_tokens(tokens);
3339 for input in self.inputs.pairs() {
3340 match **input.value() {
3341 FnArg::Captured(ArgCaptured {
3342 ref pat,
3343 ty: Type::Infer(_),
3344 ..
3345 }) => {
3346 pat.to_tokens(tokens);
3347 }
3348 _ => input.value().to_tokens(tokens),
3349 }
3350 input.punct().to_tokens(tokens);
3351 }
3352 self.or2_token.to_tokens(tokens);
3353 self.output.to_tokens(tokens);
3354 self.body.to_tokens(tokens);
3355 }
3356 }
3357
3358 #[cfg(feature = "full")]
3359 impl ToTokens for ExprUnsafe {
to_tokens(&self, tokens: &mut TokenStream)3360 fn to_tokens(&self, tokens: &mut TokenStream) {
3361 outer_attrs_to_tokens(&self.attrs, tokens);
3362 self.unsafe_token.to_tokens(tokens);
3363 self.block.brace_token.surround(tokens, |tokens| {
3364 inner_attrs_to_tokens(&self.attrs, tokens);
3365 tokens.append_all(&self.block.stmts);
3366 });
3367 }
3368 }
3369
3370 #[cfg(feature = "full")]
3371 impl ToTokens for ExprBlock {
to_tokens(&self, tokens: &mut TokenStream)3372 fn to_tokens(&self, tokens: &mut TokenStream) {
3373 outer_attrs_to_tokens(&self.attrs, tokens);
3374 self.label.to_tokens(tokens);
3375 self.block.brace_token.surround(tokens, |tokens| {
3376 inner_attrs_to_tokens(&self.attrs, tokens);
3377 tokens.append_all(&self.block.stmts);
3378 });
3379 }
3380 }
3381
3382 #[cfg(feature = "full")]
3383 impl ToTokens for ExprAssign {
to_tokens(&self, tokens: &mut TokenStream)3384 fn to_tokens(&self, tokens: &mut TokenStream) {
3385 outer_attrs_to_tokens(&self.attrs, tokens);
3386 self.left.to_tokens(tokens);
3387 self.eq_token.to_tokens(tokens);
3388 self.right.to_tokens(tokens);
3389 }
3390 }
3391
3392 #[cfg(feature = "full")]
3393 impl ToTokens for ExprAssignOp {
to_tokens(&self, tokens: &mut TokenStream)3394 fn to_tokens(&self, tokens: &mut TokenStream) {
3395 outer_attrs_to_tokens(&self.attrs, tokens);
3396 self.left.to_tokens(tokens);
3397 self.op.to_tokens(tokens);
3398 self.right.to_tokens(tokens);
3399 }
3400 }
3401
3402 impl ToTokens for ExprField {
to_tokens(&self, tokens: &mut TokenStream)3403 fn to_tokens(&self, tokens: &mut TokenStream) {
3404 outer_attrs_to_tokens(&self.attrs, tokens);
3405 self.base.to_tokens(tokens);
3406 self.dot_token.to_tokens(tokens);
3407 self.member.to_tokens(tokens);
3408 }
3409 }
3410
3411 impl ToTokens for Member {
to_tokens(&self, tokens: &mut TokenStream)3412 fn to_tokens(&self, tokens: &mut TokenStream) {
3413 match *self {
3414 Member::Named(ref ident) => ident.to_tokens(tokens),
3415 Member::Unnamed(ref index) => index.to_tokens(tokens),
3416 }
3417 }
3418 }
3419
3420 impl ToTokens for Index {
to_tokens(&self, tokens: &mut TokenStream)3421 fn to_tokens(&self, tokens: &mut TokenStream) {
3422 let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
3423 lit.set_span(self.span);
3424 tokens.append(lit);
3425 }
3426 }
3427
3428 impl ToTokens for ExprIndex {
to_tokens(&self, tokens: &mut TokenStream)3429 fn to_tokens(&self, tokens: &mut TokenStream) {
3430 outer_attrs_to_tokens(&self.attrs, tokens);
3431 self.expr.to_tokens(tokens);
3432 self.bracket_token.surround(tokens, |tokens| {
3433 self.index.to_tokens(tokens);
3434 });
3435 }
3436 }
3437
3438 #[cfg(feature = "full")]
3439 impl ToTokens for ExprRange {
to_tokens(&self, tokens: &mut TokenStream)3440 fn to_tokens(&self, tokens: &mut TokenStream) {
3441 outer_attrs_to_tokens(&self.attrs, tokens);
3442 self.from.to_tokens(tokens);
3443 match self.limits {
3444 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
3445 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
3446 }
3447 self.to.to_tokens(tokens);
3448 }
3449 }
3450
3451 impl ToTokens for ExprPath {
to_tokens(&self, tokens: &mut TokenStream)3452 fn to_tokens(&self, tokens: &mut TokenStream) {
3453 outer_attrs_to_tokens(&self.attrs, tokens);
3454 private::print_path(tokens, &self.qself, &self.path);
3455 }
3456 }
3457
3458 #[cfg(feature = "full")]
3459 impl ToTokens for ExprReference {
to_tokens(&self, tokens: &mut TokenStream)3460 fn to_tokens(&self, tokens: &mut TokenStream) {
3461 outer_attrs_to_tokens(&self.attrs, tokens);
3462 self.and_token.to_tokens(tokens);
3463 self.mutability.to_tokens(tokens);
3464 self.expr.to_tokens(tokens);
3465 }
3466 }
3467
3468 #[cfg(feature = "full")]
3469 impl ToTokens for ExprBreak {
to_tokens(&self, tokens: &mut TokenStream)3470 fn to_tokens(&self, tokens: &mut TokenStream) {
3471 outer_attrs_to_tokens(&self.attrs, tokens);
3472 self.break_token.to_tokens(tokens);
3473 self.label.to_tokens(tokens);
3474 self.expr.to_tokens(tokens);
3475 }
3476 }
3477
3478 #[cfg(feature = "full")]
3479 impl ToTokens for ExprContinue {
to_tokens(&self, tokens: &mut TokenStream)3480 fn to_tokens(&self, tokens: &mut TokenStream) {
3481 outer_attrs_to_tokens(&self.attrs, tokens);
3482 self.continue_token.to_tokens(tokens);
3483 self.label.to_tokens(tokens);
3484 }
3485 }
3486
3487 #[cfg(feature = "full")]
3488 impl ToTokens for ExprReturn {
to_tokens(&self, tokens: &mut TokenStream)3489 fn to_tokens(&self, tokens: &mut TokenStream) {
3490 outer_attrs_to_tokens(&self.attrs, tokens);
3491 self.return_token.to_tokens(tokens);
3492 self.expr.to_tokens(tokens);
3493 }
3494 }
3495
3496 #[cfg(feature = "full")]
3497 impl ToTokens for ExprMacro {
to_tokens(&self, tokens: &mut TokenStream)3498 fn to_tokens(&self, tokens: &mut TokenStream) {
3499 outer_attrs_to_tokens(&self.attrs, tokens);
3500 self.mac.to_tokens(tokens);
3501 }
3502 }
3503
3504 #[cfg(feature = "full")]
3505 impl ToTokens for ExprStruct {
to_tokens(&self, tokens: &mut TokenStream)3506 fn to_tokens(&self, tokens: &mut TokenStream) {
3507 outer_attrs_to_tokens(&self.attrs, tokens);
3508 self.path.to_tokens(tokens);
3509 self.brace_token.surround(tokens, |tokens| {
3510 inner_attrs_to_tokens(&self.attrs, tokens);
3511 self.fields.to_tokens(tokens);
3512 if self.rest.is_some() {
3513 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
3514 self.rest.to_tokens(tokens);
3515 }
3516 })
3517 }
3518 }
3519
3520 #[cfg(feature = "full")]
3521 impl ToTokens for ExprRepeat {
to_tokens(&self, tokens: &mut TokenStream)3522 fn to_tokens(&self, tokens: &mut TokenStream) {
3523 outer_attrs_to_tokens(&self.attrs, tokens);
3524 self.bracket_token.surround(tokens, |tokens| {
3525 inner_attrs_to_tokens(&self.attrs, tokens);
3526 self.expr.to_tokens(tokens);
3527 self.semi_token.to_tokens(tokens);
3528 self.len.to_tokens(tokens);
3529 })
3530 }
3531 }
3532
3533 #[cfg(feature = "full")]
3534 impl ToTokens for ExprGroup {
to_tokens(&self, tokens: &mut TokenStream)3535 fn to_tokens(&self, tokens: &mut TokenStream) {
3536 outer_attrs_to_tokens(&self.attrs, tokens);
3537 self.group_token.surround(tokens, |tokens| {
3538 self.expr.to_tokens(tokens);
3539 });
3540 }
3541 }
3542
3543 impl ToTokens for ExprParen {
to_tokens(&self, tokens: &mut TokenStream)3544 fn to_tokens(&self, tokens: &mut TokenStream) {
3545 outer_attrs_to_tokens(&self.attrs, tokens);
3546 self.paren_token.surround(tokens, |tokens| {
3547 inner_attrs_to_tokens(&self.attrs, tokens);
3548 self.expr.to_tokens(tokens);
3549 });
3550 }
3551 }
3552
3553 #[cfg(feature = "full")]
3554 impl ToTokens for ExprTry {
to_tokens(&self, tokens: &mut TokenStream)3555 fn to_tokens(&self, tokens: &mut TokenStream) {
3556 outer_attrs_to_tokens(&self.attrs, tokens);
3557 self.expr.to_tokens(tokens);
3558 self.question_token.to_tokens(tokens);
3559 }
3560 }
3561
3562 impl ToTokens for ExprVerbatim {
to_tokens(&self, tokens: &mut TokenStream)3563 fn to_tokens(&self, tokens: &mut TokenStream) {
3564 self.tts.to_tokens(tokens);
3565 }
3566 }
3567
3568 #[cfg(feature = "full")]
3569 impl ToTokens for Label {
to_tokens(&self, tokens: &mut TokenStream)3570 fn to_tokens(&self, tokens: &mut TokenStream) {
3571 self.name.to_tokens(tokens);
3572 self.colon_token.to_tokens(tokens);
3573 }
3574 }
3575
3576 #[cfg(feature = "full")]
3577 impl ToTokens for FieldValue {
to_tokens(&self, tokens: &mut TokenStream)3578 fn to_tokens(&self, tokens: &mut TokenStream) {
3579 outer_attrs_to_tokens(&self.attrs, tokens);
3580 self.member.to_tokens(tokens);
3581 if let Some(ref colon_token) = self.colon_token {
3582 colon_token.to_tokens(tokens);
3583 self.expr.to_tokens(tokens);
3584 }
3585 }
3586 }
3587
3588 #[cfg(feature = "full")]
3589 impl ToTokens for Arm {
to_tokens(&self, tokens: &mut TokenStream)3590 fn to_tokens(&self, tokens: &mut TokenStream) {
3591 tokens.append_all(&self.attrs);
3592 self.leading_vert.to_tokens(tokens);
3593 self.pats.to_tokens(tokens);
3594 if let Some((ref if_token, ref guard)) = self.guard {
3595 if_token.to_tokens(tokens);
3596 guard.to_tokens(tokens);
3597 }
3598 self.fat_arrow_token.to_tokens(tokens);
3599 self.body.to_tokens(tokens);
3600 self.comma.to_tokens(tokens);
3601 }
3602 }
3603
3604 #[cfg(feature = "full")]
3605 impl ToTokens for PatWild {
to_tokens(&self, tokens: &mut TokenStream)3606 fn to_tokens(&self, tokens: &mut TokenStream) {
3607 self.underscore_token.to_tokens(tokens);
3608 }
3609 }
3610
3611 #[cfg(feature = "full")]
3612 impl ToTokens for PatIdent {
to_tokens(&self, tokens: &mut TokenStream)3613 fn to_tokens(&self, tokens: &mut TokenStream) {
3614 self.by_ref.to_tokens(tokens);
3615 self.mutability.to_tokens(tokens);
3616 self.ident.to_tokens(tokens);
3617 if let Some((ref at_token, ref subpat)) = self.subpat {
3618 at_token.to_tokens(tokens);
3619 subpat.to_tokens(tokens);
3620 }
3621 }
3622 }
3623
3624 #[cfg(feature = "full")]
3625 impl ToTokens for PatStruct {
to_tokens(&self, tokens: &mut TokenStream)3626 fn to_tokens(&self, tokens: &mut TokenStream) {
3627 self.path.to_tokens(tokens);
3628 self.brace_token.surround(tokens, |tokens| {
3629 self.fields.to_tokens(tokens);
3630 // NOTE: We need a comma before the dot2 token if it is present.
3631 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
3632 <Token![,]>::default().to_tokens(tokens);
3633 }
3634 self.dot2_token.to_tokens(tokens);
3635 });
3636 }
3637 }
3638
3639 #[cfg(feature = "full")]
3640 impl ToTokens for PatTupleStruct {
to_tokens(&self, tokens: &mut TokenStream)3641 fn to_tokens(&self, tokens: &mut TokenStream) {
3642 self.path.to_tokens(tokens);
3643 self.pat.to_tokens(tokens);
3644 }
3645 }
3646
3647 #[cfg(feature = "full")]
3648 impl ToTokens for PatPath {
to_tokens(&self, tokens: &mut TokenStream)3649 fn to_tokens(&self, tokens: &mut TokenStream) {
3650 private::print_path(tokens, &self.qself, &self.path);
3651 }
3652 }
3653
3654 #[cfg(feature = "full")]
3655 impl ToTokens for PatTuple {
to_tokens(&self, tokens: &mut TokenStream)3656 fn to_tokens(&self, tokens: &mut TokenStream) {
3657 self.paren_token.surround(tokens, |tokens| {
3658 self.front.to_tokens(tokens);
3659 if let Some(ref dot2_token) = self.dot2_token {
3660 if !self.front.empty_or_trailing() {
3661 // Ensure there is a comma before the .. token.
3662 <Token![,]>::default().to_tokens(tokens);
3663 }
3664 dot2_token.to_tokens(tokens);
3665 self.comma_token.to_tokens(tokens);
3666 if self.comma_token.is_none() && !self.back.is_empty() {
3667 // Ensure there is a comma after the .. token.
3668 <Token![,]>::default().to_tokens(tokens);
3669 }
3670 }
3671 self.back.to_tokens(tokens);
3672 });
3673 }
3674 }
3675
3676 #[cfg(feature = "full")]
3677 impl ToTokens for PatBox {
to_tokens(&self, tokens: &mut TokenStream)3678 fn to_tokens(&self, tokens: &mut TokenStream) {
3679 self.box_token.to_tokens(tokens);
3680 self.pat.to_tokens(tokens);
3681 }
3682 }
3683
3684 #[cfg(feature = "full")]
3685 impl ToTokens for PatRef {
to_tokens(&self, tokens: &mut TokenStream)3686 fn to_tokens(&self, tokens: &mut TokenStream) {
3687 self.and_token.to_tokens(tokens);
3688 self.mutability.to_tokens(tokens);
3689 self.pat.to_tokens(tokens);
3690 }
3691 }
3692
3693 #[cfg(feature = "full")]
3694 impl ToTokens for PatLit {
to_tokens(&self, tokens: &mut TokenStream)3695 fn to_tokens(&self, tokens: &mut TokenStream) {
3696 self.expr.to_tokens(tokens);
3697 }
3698 }
3699
3700 #[cfg(feature = "full")]
3701 impl ToTokens for PatRange {
to_tokens(&self, tokens: &mut TokenStream)3702 fn to_tokens(&self, tokens: &mut TokenStream) {
3703 self.lo.to_tokens(tokens);
3704 match self.limits {
3705 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
3706 RangeLimits::Closed(ref t) => Token![...](t.spans).to_tokens(tokens),
3707 }
3708 self.hi.to_tokens(tokens);
3709 }
3710 }
3711
3712 #[cfg(feature = "full")]
3713 impl ToTokens for PatSlice {
to_tokens(&self, tokens: &mut TokenStream)3714 fn to_tokens(&self, tokens: &mut TokenStream) {
3715 self.bracket_token.surround(tokens, |tokens| {
3716 self.front.to_tokens(tokens);
3717
3718 // If we need a comma before the middle or standalone .. token,
3719 // then make sure it's present.
3720 if !self.front.empty_or_trailing()
3721 && (self.middle.is_some() || self.dot2_token.is_some())
3722 {
3723 <Token![,]>::default().to_tokens(tokens);
3724 }
3725
3726 // If we have an identifier, we always need a .. token.
3727 if self.middle.is_some() {
3728 self.middle.to_tokens(tokens);
3729 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
3730 } else if self.dot2_token.is_some() {
3731 self.dot2_token.to_tokens(tokens);
3732 }
3733
3734 // Make sure we have a comma before the back half.
3735 if !self.back.is_empty() {
3736 TokensOrDefault(&self.comma_token).to_tokens(tokens);
3737 self.back.to_tokens(tokens);
3738 } else {
3739 self.comma_token.to_tokens(tokens);
3740 }
3741 })
3742 }
3743 }
3744
3745 #[cfg(feature = "full")]
3746 impl ToTokens for PatMacro {
to_tokens(&self, tokens: &mut TokenStream)3747 fn to_tokens(&self, tokens: &mut TokenStream) {
3748 self.mac.to_tokens(tokens);
3749 }
3750 }
3751
3752 #[cfg(feature = "full")]
3753 impl ToTokens for PatVerbatim {
to_tokens(&self, tokens: &mut TokenStream)3754 fn to_tokens(&self, tokens: &mut TokenStream) {
3755 self.tts.to_tokens(tokens);
3756 }
3757 }
3758
3759 #[cfg(feature = "full")]
3760 impl ToTokens for FieldPat {
to_tokens(&self, tokens: &mut TokenStream)3761 fn to_tokens(&self, tokens: &mut TokenStream) {
3762 if let Some(ref colon_token) = self.colon_token {
3763 self.member.to_tokens(tokens);
3764 colon_token.to_tokens(tokens);
3765 }
3766 self.pat.to_tokens(tokens);
3767 }
3768 }
3769
3770 #[cfg(feature = "full")]
3771 impl ToTokens for Block {
to_tokens(&self, tokens: &mut TokenStream)3772 fn to_tokens(&self, tokens: &mut TokenStream) {
3773 self.brace_token.surround(tokens, |tokens| {
3774 tokens.append_all(&self.stmts);
3775 });
3776 }
3777 }
3778
3779 #[cfg(feature = "full")]
3780 impl ToTokens for Stmt {
to_tokens(&self, tokens: &mut TokenStream)3781 fn to_tokens(&self, tokens: &mut TokenStream) {
3782 match *self {
3783 Stmt::Local(ref local) => local.to_tokens(tokens),
3784 Stmt::Item(ref item) => item.to_tokens(tokens),
3785 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
3786 Stmt::Semi(ref expr, ref semi) => {
3787 expr.to_tokens(tokens);
3788 semi.to_tokens(tokens);
3789 }
3790 }
3791 }
3792 }
3793
3794 #[cfg(feature = "full")]
3795 impl ToTokens for Local {
to_tokens(&self, tokens: &mut TokenStream)3796 fn to_tokens(&self, tokens: &mut TokenStream) {
3797 outer_attrs_to_tokens(&self.attrs, tokens);
3798 self.let_token.to_tokens(tokens);
3799 self.pats.to_tokens(tokens);
3800 if let Some((ref colon_token, ref ty)) = self.ty {
3801 colon_token.to_tokens(tokens);
3802 ty.to_tokens(tokens);
3803 }
3804 if let Some((ref eq_token, ref init)) = self.init {
3805 eq_token.to_tokens(tokens);
3806 init.to_tokens(tokens);
3807 }
3808 self.semi_token.to_tokens(tokens);
3809 }
3810 }
3811 }
3812