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