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