syn/
expr.rs

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