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