syn_pub_items/
expr.rs

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