1 use super::*;
2 use crate::punctuated::Punctuated;
3 #[cfg(feature = "extra-traits")]
4 use crate::tt::TokenStreamHelper;
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 #manual_extra_traits {
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 #[cfg(feature = "extra-traits")]
724 impl Eq for Expr {}
725 
726 #[cfg(feature = "extra-traits")]
727 impl PartialEq for Expr {
eq(&self, other: &Self) -> bool728     fn eq(&self, other: &Self) -> bool {
729         match (self, other) {
730             (Expr::Array(this), Expr::Array(other)) => this == other,
731             (Expr::Assign(this), Expr::Assign(other)) => this == other,
732             (Expr::AssignOp(this), Expr::AssignOp(other)) => this == other,
733             (Expr::Async(this), Expr::Async(other)) => this == other,
734             (Expr::Await(this), Expr::Await(other)) => this == other,
735             (Expr::Binary(this), Expr::Binary(other)) => this == other,
736             (Expr::Block(this), Expr::Block(other)) => this == other,
737             (Expr::Box(this), Expr::Box(other)) => this == other,
738             (Expr::Break(this), Expr::Break(other)) => this == other,
739             (Expr::Call(this), Expr::Call(other)) => this == other,
740             (Expr::Cast(this), Expr::Cast(other)) => this == other,
741             (Expr::Closure(this), Expr::Closure(other)) => this == other,
742             (Expr::Continue(this), Expr::Continue(other)) => this == other,
743             (Expr::Field(this), Expr::Field(other)) => this == other,
744             (Expr::ForLoop(this), Expr::ForLoop(other)) => this == other,
745             (Expr::Group(this), Expr::Group(other)) => this == other,
746             (Expr::If(this), Expr::If(other)) => this == other,
747             (Expr::Index(this), Expr::Index(other)) => this == other,
748             (Expr::Let(this), Expr::Let(other)) => this == other,
749             (Expr::Lit(this), Expr::Lit(other)) => this == other,
750             (Expr::Loop(this), Expr::Loop(other)) => this == other,
751             (Expr::Macro(this), Expr::Macro(other)) => this == other,
752             (Expr::Match(this), Expr::Match(other)) => this == other,
753             (Expr::MethodCall(this), Expr::MethodCall(other)) => this == other,
754             (Expr::Paren(this), Expr::Paren(other)) => this == other,
755             (Expr::Path(this), Expr::Path(other)) => this == other,
756             (Expr::Range(this), Expr::Range(other)) => this == other,
757             (Expr::Reference(this), Expr::Reference(other)) => this == other,
758             (Expr::Repeat(this), Expr::Repeat(other)) => this == other,
759             (Expr::Return(this), Expr::Return(other)) => this == other,
760             (Expr::Struct(this), Expr::Struct(other)) => this == other,
761             (Expr::Try(this), Expr::Try(other)) => this == other,
762             (Expr::TryBlock(this), Expr::TryBlock(other)) => this == other,
763             (Expr::Tuple(this), Expr::Tuple(other)) => this == other,
764             (Expr::Type(this), Expr::Type(other)) => this == other,
765             (Expr::Unary(this), Expr::Unary(other)) => this == other,
766             (Expr::Unsafe(this), Expr::Unsafe(other)) => this == other,
767             (Expr::Verbatim(this), Expr::Verbatim(other)) => {
768                 TokenStreamHelper(this) == TokenStreamHelper(other)
769             }
770             (Expr::While(this), Expr::While(other)) => this == other,
771             (Expr::Yield(this), Expr::Yield(other)) => this == other,
772             _ => false,
773         }
774     }
775 }
776 
777 #[cfg(feature = "extra-traits")]
778 impl Hash for Expr {
hash<H>(&self, hash: &mut H) where H: Hasher,779     fn hash<H>(&self, hash: &mut H)
780     where
781         H: Hasher,
782     {
783         match self {
784             Expr::Array(expr) => {
785                 hash.write_u8(0);
786                 expr.hash(hash);
787             }
788             Expr::Assign(expr) => {
789                 hash.write_u8(1);
790                 expr.hash(hash);
791             }
792             Expr::AssignOp(expr) => {
793                 hash.write_u8(2);
794                 expr.hash(hash);
795             }
796             Expr::Async(expr) => {
797                 hash.write_u8(3);
798                 expr.hash(hash);
799             }
800             Expr::Await(expr) => {
801                 hash.write_u8(4);
802                 expr.hash(hash);
803             }
804             Expr::Binary(expr) => {
805                 hash.write_u8(5);
806                 expr.hash(hash);
807             }
808             Expr::Block(expr) => {
809                 hash.write_u8(6);
810                 expr.hash(hash);
811             }
812             Expr::Box(expr) => {
813                 hash.write_u8(7);
814                 expr.hash(hash);
815             }
816             Expr::Break(expr) => {
817                 hash.write_u8(8);
818                 expr.hash(hash);
819             }
820             Expr::Call(expr) => {
821                 hash.write_u8(9);
822                 expr.hash(hash);
823             }
824             Expr::Cast(expr) => {
825                 hash.write_u8(10);
826                 expr.hash(hash);
827             }
828             Expr::Closure(expr) => {
829                 hash.write_u8(11);
830                 expr.hash(hash);
831             }
832             Expr::Continue(expr) => {
833                 hash.write_u8(12);
834                 expr.hash(hash);
835             }
836             Expr::Field(expr) => {
837                 hash.write_u8(13);
838                 expr.hash(hash);
839             }
840             Expr::ForLoop(expr) => {
841                 hash.write_u8(14);
842                 expr.hash(hash);
843             }
844             Expr::Group(expr) => {
845                 hash.write_u8(15);
846                 expr.hash(hash);
847             }
848             Expr::If(expr) => {
849                 hash.write_u8(16);
850                 expr.hash(hash);
851             }
852             Expr::Index(expr) => {
853                 hash.write_u8(17);
854                 expr.hash(hash);
855             }
856             Expr::Let(expr) => {
857                 hash.write_u8(18);
858                 expr.hash(hash);
859             }
860             Expr::Lit(expr) => {
861                 hash.write_u8(19);
862                 expr.hash(hash);
863             }
864             Expr::Loop(expr) => {
865                 hash.write_u8(20);
866                 expr.hash(hash);
867             }
868             Expr::Macro(expr) => {
869                 hash.write_u8(21);
870                 expr.hash(hash);
871             }
872             Expr::Match(expr) => {
873                 hash.write_u8(22);
874                 expr.hash(hash);
875             }
876             Expr::MethodCall(expr) => {
877                 hash.write_u8(23);
878                 expr.hash(hash);
879             }
880             Expr::Paren(expr) => {
881                 hash.write_u8(24);
882                 expr.hash(hash);
883             }
884             Expr::Path(expr) => {
885                 hash.write_u8(25);
886                 expr.hash(hash);
887             }
888             Expr::Range(expr) => {
889                 hash.write_u8(26);
890                 expr.hash(hash);
891             }
892             Expr::Reference(expr) => {
893                 hash.write_u8(27);
894                 expr.hash(hash);
895             }
896             Expr::Repeat(expr) => {
897                 hash.write_u8(28);
898                 expr.hash(hash);
899             }
900             Expr::Return(expr) => {
901                 hash.write_u8(29);
902                 expr.hash(hash);
903             }
904             Expr::Struct(expr) => {
905                 hash.write_u8(30);
906                 expr.hash(hash);
907             }
908             Expr::Try(expr) => {
909                 hash.write_u8(31);
910                 expr.hash(hash);
911             }
912             Expr::TryBlock(expr) => {
913                 hash.write_u8(32);
914                 expr.hash(hash);
915             }
916             Expr::Tuple(expr) => {
917                 hash.write_u8(33);
918                 expr.hash(hash);
919             }
920             Expr::Type(expr) => {
921                 hash.write_u8(34);
922                 expr.hash(hash);
923             }
924             Expr::Unary(expr) => {
925                 hash.write_u8(35);
926                 expr.hash(hash);
927             }
928             Expr::Unsafe(expr) => {
929                 hash.write_u8(36);
930                 expr.hash(hash);
931             }
932             Expr::Verbatim(expr) => {
933                 hash.write_u8(37);
934                 TokenStreamHelper(expr).hash(hash);
935             }
936             Expr::While(expr) => {
937                 hash.write_u8(38);
938                 expr.hash(hash);
939             }
940             Expr::Yield(expr) => {
941                 hash.write_u8(39);
942                 expr.hash(hash);
943             }
944             Expr::__Nonexhaustive => unreachable!(),
945         }
946     }
947 }
948 
949 impl Expr {
950     #[cfg(all(feature = "parsing", feature = "full"))]
replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute>951     pub(crate) fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
952         match self {
953             Expr::Box(ExprBox { attrs, .. })
954             | Expr::Array(ExprArray { attrs, .. })
955             | Expr::Call(ExprCall { attrs, .. })
956             | Expr::MethodCall(ExprMethodCall { attrs, .. })
957             | Expr::Tuple(ExprTuple { attrs, .. })
958             | Expr::Binary(ExprBinary { attrs, .. })
959             | Expr::Unary(ExprUnary { attrs, .. })
960             | Expr::Lit(ExprLit { attrs, .. })
961             | Expr::Cast(ExprCast { attrs, .. })
962             | Expr::Type(ExprType { attrs, .. })
963             | Expr::Let(ExprLet { attrs, .. })
964             | Expr::If(ExprIf { attrs, .. })
965             | Expr::While(ExprWhile { attrs, .. })
966             | Expr::ForLoop(ExprForLoop { attrs, .. })
967             | Expr::Loop(ExprLoop { attrs, .. })
968             | Expr::Match(ExprMatch { attrs, .. })
969             | Expr::Closure(ExprClosure { attrs, .. })
970             | Expr::Unsafe(ExprUnsafe { attrs, .. })
971             | Expr::Block(ExprBlock { attrs, .. })
972             | Expr::Assign(ExprAssign { attrs, .. })
973             | Expr::AssignOp(ExprAssignOp { attrs, .. })
974             | Expr::Field(ExprField { attrs, .. })
975             | Expr::Index(ExprIndex { attrs, .. })
976             | Expr::Range(ExprRange { attrs, .. })
977             | Expr::Path(ExprPath { attrs, .. })
978             | Expr::Reference(ExprReference { attrs, .. })
979             | Expr::Break(ExprBreak { attrs, .. })
980             | Expr::Continue(ExprContinue { attrs, .. })
981             | Expr::Return(ExprReturn { attrs, .. })
982             | Expr::Macro(ExprMacro { attrs, .. })
983             | Expr::Struct(ExprStruct { attrs, .. })
984             | Expr::Repeat(ExprRepeat { attrs, .. })
985             | Expr::Paren(ExprParen { attrs, .. })
986             | Expr::Group(ExprGroup { attrs, .. })
987             | Expr::Try(ExprTry { attrs, .. })
988             | Expr::Async(ExprAsync { attrs, .. })
989             | Expr::Await(ExprAwait { attrs, .. })
990             | Expr::TryBlock(ExprTryBlock { attrs, .. })
991             | Expr::Yield(ExprYield { attrs, .. }) => mem::replace(attrs, new),
992             Expr::Verbatim(_) => Vec::new(),
993             Expr::__Nonexhaustive => unreachable!(),
994         }
995     }
996 }
997 
998 ast_enum! {
999     /// A struct or tuple struct field accessed in a struct literal or field
1000     /// expression.
1001     ///
1002     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
1003     /// feature.*
1004     #[derive(Eq, PartialEq, Hash)]
1005     pub enum Member #manual_extra_traits {
1006         /// A named field like `self.x`.
1007         Named(Ident),
1008         /// An unnamed field like `self.0`.
1009         Unnamed(Index),
1010     }
1011 }
1012 
1013 #[cfg(feature = "printing")]
1014 impl IdentFragment for Member {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result1015     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1016         match self {
1017             Member::Named(m) => Display::fmt(m, formatter),
1018             Member::Unnamed(m) => Display::fmt(&m.index, formatter),
1019         }
1020     }
1021 
span(&self) -> Option<Span>1022     fn span(&self) -> Option<Span> {
1023         match self {
1024             Member::Named(m) => Some(m.span()),
1025             Member::Unnamed(m) => Some(m.span),
1026         }
1027     }
1028 }
1029 
1030 ast_struct! {
1031     /// The index of an unnamed tuple struct field.
1032     ///
1033     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
1034     /// feature.*
1035     pub struct Index #manual_extra_traits {
1036         pub index: u32,
1037         pub span: Span,
1038     }
1039 }
1040 
1041 impl From<usize> for Index {
from(index: usize) -> Index1042     fn from(index: usize) -> Index {
1043         assert!(index < u32::max_value() as usize);
1044         Index {
1045             index: index as u32,
1046             span: Span::call_site(),
1047         }
1048     }
1049 }
1050 
1051 impl Eq for Index {}
1052 
1053 impl PartialEq for Index {
eq(&self, other: &Self) -> bool1054     fn eq(&self, other: &Self) -> bool {
1055         self.index == other.index
1056     }
1057 }
1058 
1059 impl Hash for Index {
hash<H: Hasher>(&self, state: &mut H)1060     fn hash<H: Hasher>(&self, state: &mut H) {
1061         self.index.hash(state);
1062     }
1063 }
1064 
1065 #[cfg(feature = "printing")]
1066 impl IdentFragment for Index {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result1067     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1068         Display::fmt(&self.index, formatter)
1069     }
1070 
span(&self) -> Option<Span>1071     fn span(&self) -> Option<Span> {
1072         Some(self.span)
1073     }
1074 }
1075 
1076 #[cfg(feature = "full")]
1077 ast_struct! {
1078     #[derive(Default)]
1079     pub struct Reserved {
1080         _private: (),
1081     }
1082 }
1083 
1084 #[cfg(feature = "full")]
1085 ast_struct! {
1086     /// The `::<>` explicit type parameters passed to a method call:
1087     /// `parse::<u64>()`.
1088     ///
1089     /// *This type is available only if Syn is built with the `"full"` feature.*
1090     pub struct MethodTurbofish {
1091         pub colon2_token: Token![::],
1092         pub lt_token: Token![<],
1093         pub args: Punctuated<GenericMethodArgument, Token![,]>,
1094         pub gt_token: Token![>],
1095     }
1096 }
1097 
1098 #[cfg(feature = "full")]
1099 ast_enum! {
1100     /// An individual generic argument to a method, like `T`.
1101     ///
1102     /// *This type is available only if Syn is built with the `"full"` feature.*
1103     pub enum GenericMethodArgument {
1104         /// A type argument.
1105         Type(Type),
1106         /// A const expression. Must be inside of a block.
1107         ///
1108         /// NOTE: Identity expressions are represented as Type arguments, as
1109         /// they are indistinguishable syntactically.
1110         Const(Expr),
1111     }
1112 }
1113 
1114 #[cfg(feature = "full")]
1115 ast_struct! {
1116     /// A field-value pair in a struct literal.
1117     ///
1118     /// *This type is available only if Syn is built with the `"full"` feature.*
1119     pub struct FieldValue {
1120         /// Attributes tagged on the field.
1121         pub attrs: Vec<Attribute>,
1122 
1123         /// Name or index of the field.
1124         pub member: Member,
1125 
1126         /// The colon in `Struct { x: x }`. If written in shorthand like
1127         /// `Struct { x }`, there is no colon.
1128         pub colon_token: Option<Token![:]>,
1129 
1130         /// Value of the field.
1131         pub expr: Expr,
1132     }
1133 }
1134 
1135 #[cfg(feature = "full")]
1136 ast_struct! {
1137     /// A lifetime labeling a `for`, `while`, or `loop`.
1138     ///
1139     /// *This type is available only if Syn is built with the `"full"` feature.*
1140     pub struct Label {
1141         pub name: Lifetime,
1142         pub colon_token: Token![:],
1143     }
1144 }
1145 
1146 #[cfg(feature = "full")]
1147 ast_struct! {
1148     /// One arm of a `match` expression: `0...10 => { return true; }`.
1149     ///
1150     /// As in:
1151     ///
1152     /// ```
1153     /// # fn f() -> bool {
1154     /// #     let n = 0;
1155     /// match n {
1156     ///     0...10 => {
1157     ///         return true;
1158     ///     }
1159     ///     // ...
1160     ///     # _ => {}
1161     /// }
1162     /// #   false
1163     /// # }
1164     /// ```
1165     ///
1166     /// *This type is available only if Syn is built with the `"full"` feature.*
1167     pub struct Arm {
1168         pub attrs: Vec<Attribute>,
1169         pub pat: Pat,
1170         pub guard: Option<(Token![if], Box<Expr>)>,
1171         pub fat_arrow_token: Token![=>],
1172         pub body: Box<Expr>,
1173         pub comma: Option<Token![,]>,
1174     }
1175 }
1176 
1177 #[cfg(feature = "full")]
1178 ast_enum! {
1179     /// Limit types of a range, inclusive or exclusive.
1180     ///
1181     /// *This type is available only if Syn is built with the `"full"` feature.*
1182     #[cfg_attr(feature = "clone-impls", derive(Copy))]
1183     pub enum RangeLimits {
1184         /// Inclusive at the beginning, exclusive at the end.
1185         HalfOpen(Token![..]),
1186         /// Inclusive at the beginning and end.
1187         Closed(Token![..=]),
1188     }
1189 }
1190 
1191 #[cfg(any(feature = "parsing", feature = "printing"))]
1192 #[cfg(feature = "full")]
requires_terminator(expr: &Expr) -> bool1193 pub(crate) fn requires_terminator(expr: &Expr) -> bool {
1194     // see https://github.com/rust-lang/rust/blob/2679c38fc/src/librustc_ast/util/classify.rs#L7-L25
1195     match *expr {
1196         Expr::Unsafe(..)
1197         | Expr::Block(..)
1198         | Expr::If(..)
1199         | Expr::Match(..)
1200         | Expr::While(..)
1201         | Expr::Loop(..)
1202         | Expr::ForLoop(..)
1203         | Expr::Async(..)
1204         | Expr::TryBlock(..) => false,
1205         _ => true,
1206     }
1207 }
1208 
1209 #[cfg(feature = "parsing")]
1210 pub(crate) mod parsing {
1211     use super::*;
1212 
1213     use crate::parse::{Parse, ParseStream, Result};
1214     use crate::path;
1215 
1216     crate::custom_keyword!(raw);
1217 
1218     // When we're parsing expressions which occur before blocks, like in an if
1219     // statement's condition, we cannot parse a struct literal.
1220     //
1221     // Struct literals are ambiguous in certain positions
1222     // https://github.com/rust-lang/rfcs/pull/92
1223     #[derive(Copy, Clone)]
1224     pub struct AllowStruct(bool);
1225 
1226     #[derive(Copy, Clone, PartialEq, PartialOrd)]
1227     enum Precedence {
1228         Any,
1229         Assign,
1230         Range,
1231         Or,
1232         And,
1233         Compare,
1234         BitOr,
1235         BitXor,
1236         BitAnd,
1237         Shift,
1238         Arithmetic,
1239         Term,
1240         Cast,
1241     }
1242 
1243     impl Precedence {
of(op: &BinOp) -> Self1244         fn of(op: &BinOp) -> Self {
1245             match *op {
1246                 BinOp::Add(_) | BinOp::Sub(_) => Precedence::Arithmetic,
1247                 BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Term,
1248                 BinOp::And(_) => Precedence::And,
1249                 BinOp::Or(_) => Precedence::Or,
1250                 BinOp::BitXor(_) => Precedence::BitXor,
1251                 BinOp::BitAnd(_) => Precedence::BitAnd,
1252                 BinOp::BitOr(_) => Precedence::BitOr,
1253                 BinOp::Shl(_) | BinOp::Shr(_) => Precedence::Shift,
1254                 BinOp::Eq(_)
1255                 | BinOp::Lt(_)
1256                 | BinOp::Le(_)
1257                 | BinOp::Ne(_)
1258                 | BinOp::Ge(_)
1259                 | BinOp::Gt(_) => Precedence::Compare,
1260                 BinOp::AddEq(_)
1261                 | BinOp::SubEq(_)
1262                 | BinOp::MulEq(_)
1263                 | BinOp::DivEq(_)
1264                 | BinOp::RemEq(_)
1265                 | BinOp::BitXorEq(_)
1266                 | BinOp::BitAndEq(_)
1267                 | BinOp::BitOrEq(_)
1268                 | BinOp::ShlEq(_)
1269                 | BinOp::ShrEq(_) => Precedence::Assign,
1270             }
1271         }
1272     }
1273 
1274     impl Parse for Expr {
parse(input: ParseStream) -> Result<Self>1275         fn parse(input: ParseStream) -> Result<Self> {
1276             ambiguous_expr(input, AllowStruct(true))
1277         }
1278     }
1279 
1280     impl Expr {
1281         /// An alternative to the primary `Expr::parse` parser (from the
1282         /// [`Parse`] trait) for ambiguous syntactic positions in which a
1283         /// trailing brace should not be taken as part of the expression.
1284         ///
1285         /// Rust grammar has an ambiguity where braces sometimes turn a path
1286         /// expression into a struct initialization and sometimes do not. In the
1287         /// following code, the expression `S {}` is one expression. Presumably
1288         /// there is an empty struct `struct S {}` defined somewhere which it is
1289         /// instantiating.
1290         ///
1291         /// ```
1292         /// # struct S;
1293         /// # impl std::ops::Deref for S {
1294         /// #     type Target = bool;
1295         /// #     fn deref(&self) -> &Self::Target {
1296         /// #         &true
1297         /// #     }
1298         /// # }
1299         /// let _ = *S {};
1300         ///
1301         /// // parsed by rustc as: `*(S {})`
1302         /// ```
1303         ///
1304         /// We would want to parse the above using `Expr::parse` after the `=`
1305         /// token.
1306         ///
1307         /// But in the following, `S {}` is *not* a struct init expression.
1308         ///
1309         /// ```
1310         /// # const S: &bool = &true;
1311         /// if *S {} {}
1312         ///
1313         /// // parsed by rustc as:
1314         /// //
1315         /// //    if (*S) {
1316         /// //        /* empty block */
1317         /// //    }
1318         /// //    {
1319         /// //        /* another empty block */
1320         /// //    }
1321         /// ```
1322         ///
1323         /// For that reason we would want to parse if-conditions using
1324         /// `Expr::parse_without_eager_brace` after the `if` token. Same for
1325         /// similar syntactic positions such as the condition expr after a
1326         /// `while` token or the expr at the top of a `match`.
1327         ///
1328         /// The Rust grammar's choices around which way this ambiguity is
1329         /// resolved at various syntactic positions is fairly arbitrary. Really
1330         /// either parse behavior could work in most positions, and language
1331         /// designers just decide each case based on which is more likely to be
1332         /// what the programmer had in mind most of the time.
1333         ///
1334         /// ```
1335         /// # struct S;
1336         /// # fn doc() -> S {
1337         /// if return S {} {}
1338         /// # unreachable!()
1339         /// # }
1340         ///
1341         /// // parsed by rustc as:
1342         /// //
1343         /// //    if (return (S {})) {
1344         /// //    }
1345         /// //
1346         /// // but could equally well have been this other arbitrary choice:
1347         /// //
1348         /// //    if (return S) {
1349         /// //    }
1350         /// //    {}
1351         /// ```
1352         ///
1353         /// Note the grammar ambiguity on trailing braces is distinct from
1354         /// precedence and is not captured by assigning a precedence level to
1355         /// the braced struct init expr in relation to other operators. This can
1356         /// be illustrated by `return 0..S {}` vs `match 0..S {}`. The former
1357         /// parses as `return (0..(S {}))` implying tighter precedence for
1358         /// struct init than `..`, while the latter parses as `match (0..S) {}`
1359         /// implying tighter precedence for `..` than struct init, a
1360         /// contradiction.
1361         #[cfg(feature = "full")]
parse_without_eager_brace(input: ParseStream) -> Result<Expr>1362         pub fn parse_without_eager_brace(input: ParseStream) -> Result<Expr> {
1363             ambiguous_expr(input, AllowStruct(false))
1364         }
1365     }
1366 
1367     #[cfg(feature = "full")]
parse_expr( input: ParseStream, mut lhs: Expr, allow_struct: AllowStruct, base: Precedence, ) -> Result<Expr>1368     fn parse_expr(
1369         input: ParseStream,
1370         mut lhs: Expr,
1371         allow_struct: AllowStruct,
1372         base: Precedence,
1373     ) -> Result<Expr> {
1374         loop {
1375             if input
1376                 .fork()
1377                 .parse::<BinOp>()
1378                 .ok()
1379                 .map_or(false, |op| Precedence::of(&op) >= base)
1380             {
1381                 let op: BinOp = input.parse()?;
1382                 let precedence = Precedence::of(&op);
1383                 let mut rhs = unary_expr(input, allow_struct)?;
1384                 loop {
1385                     let next = peek_precedence(input);
1386                     if next > precedence || next == precedence && precedence == Precedence::Assign {
1387                         rhs = parse_expr(input, rhs, allow_struct, next)?;
1388                     } else {
1389                         break;
1390                     }
1391                 }
1392                 lhs = if precedence == Precedence::Assign {
1393                     Expr::AssignOp(ExprAssignOp {
1394                         attrs: Vec::new(),
1395                         left: Box::new(lhs),
1396                         op,
1397                         right: Box::new(rhs),
1398                     })
1399                 } else {
1400                     Expr::Binary(ExprBinary {
1401                         attrs: Vec::new(),
1402                         left: Box::new(lhs),
1403                         op,
1404                         right: Box::new(rhs),
1405                     })
1406                 };
1407             } else if Precedence::Assign >= base
1408                 && input.peek(Token![=])
1409                 && !input.peek(Token![==])
1410                 && !input.peek(Token![=>])
1411             {
1412                 let eq_token: Token![=] = input.parse()?;
1413                 let mut rhs = unary_expr(input, allow_struct)?;
1414                 loop {
1415                     let next = peek_precedence(input);
1416                     if next >= Precedence::Assign {
1417                         rhs = parse_expr(input, rhs, allow_struct, next)?;
1418                     } else {
1419                         break;
1420                     }
1421                 }
1422                 lhs = Expr::Assign(ExprAssign {
1423                     attrs: Vec::new(),
1424                     left: Box::new(lhs),
1425                     eq_token,
1426                     right: Box::new(rhs),
1427                 });
1428             } else if Precedence::Range >= base && input.peek(Token![..]) {
1429                 let limits: RangeLimits = input.parse()?;
1430                 let rhs = if input.is_empty()
1431                     || input.peek(Token![,])
1432                     || input.peek(Token![;])
1433                     || !allow_struct.0 && input.peek(token::Brace)
1434                 {
1435                     None
1436                 } else {
1437                     let mut rhs = unary_expr(input, allow_struct)?;
1438                     loop {
1439                         let next = peek_precedence(input);
1440                         if next > Precedence::Range {
1441                             rhs = parse_expr(input, rhs, allow_struct, next)?;
1442                         } else {
1443                             break;
1444                         }
1445                     }
1446                     Some(rhs)
1447                 };
1448                 lhs = Expr::Range(ExprRange {
1449                     attrs: Vec::new(),
1450                     from: Some(Box::new(lhs)),
1451                     limits,
1452                     to: rhs.map(Box::new),
1453                 });
1454             } else if Precedence::Cast >= base && input.peek(Token![as]) {
1455                 let as_token: Token![as] = input.parse()?;
1456                 let ty = input.call(Type::without_plus)?;
1457                 lhs = Expr::Cast(ExprCast {
1458                     attrs: Vec::new(),
1459                     expr: Box::new(lhs),
1460                     as_token,
1461                     ty: Box::new(ty),
1462                 });
1463             } else if Precedence::Cast >= base && input.peek(Token![:]) && !input.peek(Token![::]) {
1464                 let colon_token: Token![:] = input.parse()?;
1465                 let ty = input.call(Type::without_plus)?;
1466                 lhs = Expr::Type(ExprType {
1467                     attrs: Vec::new(),
1468                     expr: Box::new(lhs),
1469                     colon_token,
1470                     ty: Box::new(ty),
1471                 });
1472             } else {
1473                 break;
1474             }
1475         }
1476         Ok(lhs)
1477     }
1478 
1479     #[cfg(not(feature = "full"))]
parse_expr( input: ParseStream, mut lhs: Expr, allow_struct: AllowStruct, base: Precedence, ) -> Result<Expr>1480     fn parse_expr(
1481         input: ParseStream,
1482         mut lhs: Expr,
1483         allow_struct: AllowStruct,
1484         base: Precedence,
1485     ) -> Result<Expr> {
1486         loop {
1487             if input
1488                 .fork()
1489                 .parse::<BinOp>()
1490                 .ok()
1491                 .map_or(false, |op| Precedence::of(&op) >= base)
1492             {
1493                 let op: BinOp = input.parse()?;
1494                 let precedence = Precedence::of(&op);
1495                 let mut rhs = unary_expr(input, allow_struct)?;
1496                 loop {
1497                     let next = peek_precedence(input);
1498                     if next > precedence || next == precedence && precedence == Precedence::Assign {
1499                         rhs = parse_expr(input, rhs, allow_struct, next)?;
1500                     } else {
1501                         break;
1502                     }
1503                 }
1504                 lhs = Expr::Binary(ExprBinary {
1505                     attrs: Vec::new(),
1506                     left: Box::new(lhs),
1507                     op,
1508                     right: Box::new(rhs),
1509                 });
1510             } else if Precedence::Cast >= base && input.peek(Token![as]) {
1511                 let as_token: Token![as] = input.parse()?;
1512                 let ty = input.call(Type::without_plus)?;
1513                 lhs = Expr::Cast(ExprCast {
1514                     attrs: Vec::new(),
1515                     expr: Box::new(lhs),
1516                     as_token,
1517                     ty: Box::new(ty),
1518                 });
1519             } else {
1520                 break;
1521             }
1522         }
1523         Ok(lhs)
1524     }
1525 
peek_precedence(input: ParseStream) -> Precedence1526     fn peek_precedence(input: ParseStream) -> Precedence {
1527         if let Ok(op) = input.fork().parse() {
1528             Precedence::of(&op)
1529         } else if input.peek(Token![=]) && !input.peek(Token![=>]) {
1530             Precedence::Assign
1531         } else if input.peek(Token![..]) {
1532             Precedence::Range
1533         } else if input.peek(Token![as]) || input.peek(Token![:]) && !input.peek(Token![::]) {
1534             Precedence::Cast
1535         } else {
1536             Precedence::Any
1537         }
1538     }
1539 
1540     // Parse an arbitrary expression.
ambiguous_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1541     fn ambiguous_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1542         let lhs = unary_expr(input, allow_struct)?;
1543         parse_expr(input, lhs, allow_struct, Precedence::Any)
1544     }
1545 
1546     #[cfg(feature = "full")]
expr_attrs(input: ParseStream) -> Result<Vec<Attribute>>1547     fn expr_attrs(input: ParseStream) -> Result<Vec<Attribute>> {
1548         let mut attrs = Vec::new();
1549         loop {
1550             if input.peek(token::Group) {
1551                 let ahead = input.fork();
1552                 let group = crate::group::parse_group(&ahead)?;
1553                 if !group.content.peek(Token![#]) || group.content.peek2(Token![!]) {
1554                     break;
1555                 }
1556                 let attr = group.content.call(attr::parsing::single_parse_outer)?;
1557                 if !group.content.is_empty() {
1558                     break;
1559                 }
1560                 attrs.push(attr);
1561             } else if input.peek(Token![#]) {
1562                 attrs.push(input.call(attr::parsing::single_parse_outer)?);
1563             } else {
1564                 break;
1565             }
1566         }
1567         Ok(attrs)
1568     }
1569 
1570     // <UnOp> <trailer>
1571     // & <trailer>
1572     // &mut <trailer>
1573     // box <trailer>
1574     #[cfg(feature = "full")]
unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1575     fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1576         let begin = input.fork();
1577         let attrs = input.call(expr_attrs)?;
1578         if input.peek(Token![&]) {
1579             let and_token: Token![&] = input.parse()?;
1580             let raw: Option<raw> =
1581                 if input.peek(raw) && (input.peek2(Token![mut]) || input.peek2(Token![const])) {
1582                     Some(input.parse()?)
1583                 } else {
1584                     None
1585                 };
1586             let mutability: Option<Token![mut]> = input.parse()?;
1587             if raw.is_some() && mutability.is_none() {
1588                 input.parse::<Token![const]>()?;
1589             }
1590             let expr = Box::new(unary_expr(input, allow_struct)?);
1591             if raw.is_some() {
1592                 Ok(Expr::Verbatim(verbatim::between(begin, input)))
1593             } else {
1594                 Ok(Expr::Reference(ExprReference {
1595                     attrs,
1596                     and_token,
1597                     raw: Reserved::default(),
1598                     mutability,
1599                     expr,
1600                 }))
1601             }
1602         } else if input.peek(Token![box]) {
1603             Ok(Expr::Box(ExprBox {
1604                 attrs,
1605                 box_token: input.parse()?,
1606                 expr: Box::new(unary_expr(input, allow_struct)?),
1607             }))
1608         } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
1609             Ok(Expr::Unary(ExprUnary {
1610                 attrs,
1611                 op: input.parse()?,
1612                 expr: Box::new(unary_expr(input, allow_struct)?),
1613             }))
1614         } else {
1615             trailer_expr(attrs, input, allow_struct)
1616         }
1617     }
1618 
1619     #[cfg(not(feature = "full"))]
unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1620     fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1621         if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
1622             Ok(Expr::Unary(ExprUnary {
1623                 attrs: Vec::new(),
1624                 op: input.parse()?,
1625                 expr: Box::new(unary_expr(input, allow_struct)?),
1626             }))
1627         } else {
1628             trailer_expr(input, allow_struct)
1629         }
1630     }
1631 
1632     // <atom> (..<args>) ...
1633     // <atom> . <ident> (..<args>) ...
1634     // <atom> . <ident> ...
1635     // <atom> . <lit> ...
1636     // <atom> [ <expr> ] ...
1637     // <atom> ? ...
1638     #[cfg(feature = "full")]
trailer_expr( outer_attrs: Vec<Attribute>, input: ParseStream, allow_struct: AllowStruct, ) -> Result<Expr>1639     fn trailer_expr(
1640         outer_attrs: Vec<Attribute>,
1641         input: ParseStream,
1642         allow_struct: AllowStruct,
1643     ) -> Result<Expr> {
1644         let atom = atom_expr(input, allow_struct)?;
1645         let mut e = trailer_helper(input, atom)?;
1646 
1647         let inner_attrs = e.replace_attrs(Vec::new());
1648         let attrs = private::attrs(outer_attrs, inner_attrs);
1649         e.replace_attrs(attrs);
1650         Ok(e)
1651     }
1652 
1653     #[cfg(feature = "full")]
trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr>1654     fn trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr> {
1655         loop {
1656             if input.peek(token::Paren) {
1657                 let content;
1658                 e = Expr::Call(ExprCall {
1659                     attrs: Vec::new(),
1660                     func: Box::new(e),
1661                     paren_token: parenthesized!(content in input),
1662                     args: content.parse_terminated(Expr::parse)?,
1663                 });
1664             } else if input.peek(Token![.]) && !input.peek(Token![..]) {
1665                 let mut dot_token: Token![.] = input.parse()?;
1666 
1667                 let await_token: Option<token::Await> = input.parse()?;
1668                 if let Some(await_token) = await_token {
1669                     e = Expr::Await(ExprAwait {
1670                         attrs: Vec::new(),
1671                         base: Box::new(e),
1672                         dot_token,
1673                         await_token,
1674                     });
1675                     continue;
1676                 }
1677 
1678                 let float_token: Option<LitFloat> = input.parse()?;
1679                 if let Some(float_token) = float_token {
1680                     if multi_index(&mut e, &mut dot_token, float_token)? {
1681                         continue;
1682                     }
1683                 }
1684 
1685                 let member: Member = input.parse()?;
1686                 let turbofish = if member.is_named() && input.peek(Token![::]) {
1687                     Some(MethodTurbofish {
1688                         colon2_token: input.parse()?,
1689                         lt_token: input.parse()?,
1690                         args: {
1691                             let mut args = Punctuated::new();
1692                             loop {
1693                                 if input.peek(Token![>]) {
1694                                     break;
1695                                 }
1696                                 let value = input.call(generic_method_argument)?;
1697                                 args.push_value(value);
1698                                 if input.peek(Token![>]) {
1699                                     break;
1700                                 }
1701                                 let punct = input.parse()?;
1702                                 args.push_punct(punct);
1703                             }
1704                             args
1705                         },
1706                         gt_token: input.parse()?,
1707                     })
1708                 } else {
1709                     None
1710                 };
1711 
1712                 if turbofish.is_some() || input.peek(token::Paren) {
1713                     if let Member::Named(method) = member {
1714                         let content;
1715                         e = Expr::MethodCall(ExprMethodCall {
1716                             attrs: Vec::new(),
1717                             receiver: Box::new(e),
1718                             dot_token,
1719                             method,
1720                             turbofish,
1721                             paren_token: parenthesized!(content in input),
1722                             args: content.parse_terminated(Expr::parse)?,
1723                         });
1724                         continue;
1725                     }
1726                 }
1727 
1728                 e = Expr::Field(ExprField {
1729                     attrs: Vec::new(),
1730                     base: Box::new(e),
1731                     dot_token,
1732                     member,
1733                 });
1734             } else if input.peek(token::Bracket) {
1735                 let content;
1736                 e = Expr::Index(ExprIndex {
1737                     attrs: Vec::new(),
1738                     expr: Box::new(e),
1739                     bracket_token: bracketed!(content in input),
1740                     index: content.parse()?,
1741                 });
1742             } else if input.peek(Token![?]) {
1743                 e = Expr::Try(ExprTry {
1744                     attrs: Vec::new(),
1745                     expr: Box::new(e),
1746                     question_token: input.parse()?,
1747                 });
1748             } else {
1749                 break;
1750             }
1751         }
1752         Ok(e)
1753     }
1754 
1755     #[cfg(not(feature = "full"))]
trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1756     fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1757         let mut e = atom_expr(input, allow_struct)?;
1758 
1759         loop {
1760             if input.peek(token::Paren) {
1761                 let content;
1762                 e = Expr::Call(ExprCall {
1763                     attrs: Vec::new(),
1764                     func: Box::new(e),
1765                     paren_token: parenthesized!(content in input),
1766                     args: content.parse_terminated(Expr::parse)?,
1767                 });
1768             } else if input.peek(Token![.]) && !input.peek(Token![..]) && !input.peek2(token::Await)
1769             {
1770                 let mut dot_token: Token![.] = input.parse()?;
1771                 let float_token: Option<LitFloat> = input.parse()?;
1772                 if let Some(float_token) = float_token {
1773                     if multi_index(&mut e, &mut dot_token, float_token)? {
1774                         continue;
1775                     }
1776                 }
1777                 e = Expr::Field(ExprField {
1778                     attrs: Vec::new(),
1779                     base: Box::new(e),
1780                     dot_token,
1781                     member: input.parse()?,
1782                 });
1783             } else if input.peek(token::Bracket) {
1784                 let content;
1785                 e = Expr::Index(ExprIndex {
1786                     attrs: Vec::new(),
1787                     expr: Box::new(e),
1788                     bracket_token: bracketed!(content in input),
1789                     index: content.parse()?,
1790                 });
1791             } else {
1792                 break;
1793             }
1794         }
1795 
1796         Ok(e)
1797     }
1798 
1799     // Parse all atomic expressions which don't have to worry about precedence
1800     // interactions, as they are fully contained.
1801     #[cfg(feature = "full")]
atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1802     fn atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1803         if input.peek(token::Group)
1804             && !input.peek2(Token![::])
1805             && !input.peek2(Token![!])
1806             && !input.peek2(token::Brace)
1807         {
1808             input.call(expr_group).map(Expr::Group)
1809         } else if input.peek(Lit) {
1810             input.parse().map(Expr::Lit)
1811         } else if input.peek(Token![async])
1812             && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace))
1813         {
1814             input.call(expr_async).map(Expr::Async)
1815         } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1816             input.call(expr_try_block).map(Expr::TryBlock)
1817         } else if input.peek(Token![|])
1818             || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move]))
1819             || input.peek(Token![static])
1820             || input.peek(Token![move])
1821         {
1822             expr_closure(input, allow_struct).map(Expr::Closure)
1823         } else if input.peek(Ident)
1824             || input.peek(Token![::])
1825             || input.peek(Token![<])
1826             || input.peek(Token![self])
1827             || input.peek(Token![Self])
1828             || input.peek(Token![super])
1829             || input.peek(Token![crate])
1830         {
1831             path_or_macro_or_struct(input, allow_struct)
1832         } else if input.peek(token::Paren) {
1833             paren_or_tuple(input)
1834         } else if input.peek(Token![break]) {
1835             expr_break(input, allow_struct).map(Expr::Break)
1836         } else if input.peek(Token![continue]) {
1837             input.call(expr_continue).map(Expr::Continue)
1838         } else if input.peek(Token![return]) {
1839             expr_ret(input, allow_struct).map(Expr::Return)
1840         } else if input.peek(token::Bracket) {
1841             array_or_repeat(input)
1842         } else if input.peek(Token![let]) {
1843             input.call(expr_let).map(Expr::Let)
1844         } else if input.peek(Token![if]) {
1845             input.parse().map(Expr::If)
1846         } else if input.peek(Token![while]) {
1847             input.parse().map(Expr::While)
1848         } else if input.peek(Token![for]) {
1849             input.parse().map(Expr::ForLoop)
1850         } else if input.peek(Token![loop]) {
1851             input.parse().map(Expr::Loop)
1852         } else if input.peek(Token![match]) {
1853             input.parse().map(Expr::Match)
1854         } else if input.peek(Token![yield]) {
1855             input.call(expr_yield).map(Expr::Yield)
1856         } else if input.peek(Token![unsafe]) {
1857             input.call(expr_unsafe).map(Expr::Unsafe)
1858         } else if input.peek(token::Brace) {
1859             input.call(expr_block).map(Expr::Block)
1860         } else if input.peek(Token![..]) {
1861             expr_range(input, allow_struct).map(Expr::Range)
1862         } else if input.peek(Lifetime) {
1863             let the_label: Label = input.parse()?;
1864             let mut expr = if input.peek(Token![while]) {
1865                 Expr::While(input.parse()?)
1866             } else if input.peek(Token![for]) {
1867                 Expr::ForLoop(input.parse()?)
1868             } else if input.peek(Token![loop]) {
1869                 Expr::Loop(input.parse()?)
1870             } else if input.peek(token::Brace) {
1871                 Expr::Block(input.call(expr_block)?)
1872             } else {
1873                 return Err(input.error("expected loop or block expression"));
1874             };
1875             match &mut expr {
1876                 Expr::While(ExprWhile { label, .. })
1877                 | Expr::ForLoop(ExprForLoop { label, .. })
1878                 | Expr::Loop(ExprLoop { label, .. })
1879                 | Expr::Block(ExprBlock { label, .. }) => *label = Some(the_label),
1880                 _ => unreachable!(),
1881             }
1882             Ok(expr)
1883         } else {
1884             Err(input.error("expected expression"))
1885         }
1886     }
1887 
1888     #[cfg(not(feature = "full"))]
atom_expr(input: ParseStream, _allow_struct: AllowStruct) -> Result<Expr>1889     fn atom_expr(input: ParseStream, _allow_struct: AllowStruct) -> Result<Expr> {
1890         if input.peek(Lit) {
1891             input.parse().map(Expr::Lit)
1892         } else if input.peek(token::Paren) {
1893             input.call(expr_paren).map(Expr::Paren)
1894         } else if input.peek(Ident)
1895             || input.peek(Token![::])
1896             || input.peek(Token![<])
1897             || input.peek(Token![self])
1898             || input.peek(Token![Self])
1899             || input.peek(Token![super])
1900             || input.peek(Token![crate])
1901         {
1902             input.parse().map(Expr::Path)
1903         } else {
1904             Err(input.error("unsupported expression; enable syn's features=[\"full\"]"))
1905         }
1906     }
1907 
1908     #[cfg(feature = "full")]
path_or_macro_or_struct(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1909     fn path_or_macro_or_struct(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1910         let expr: ExprPath = input.parse()?;
1911         if expr.qself.is_some() {
1912             return Ok(Expr::Path(expr));
1913         }
1914 
1915         if input.peek(Token![!]) && !input.peek(Token![!=]) {
1916             let mut contains_arguments = false;
1917             for segment in &expr.path.segments {
1918                 match segment.arguments {
1919                     PathArguments::None => {}
1920                     PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
1921                         contains_arguments = true;
1922                     }
1923                 }
1924             }
1925 
1926             if !contains_arguments {
1927                 let bang_token: Token![!] = input.parse()?;
1928                 let (delimiter, tokens) = mac::parse_delimiter(input)?;
1929                 return Ok(Expr::Macro(ExprMacro {
1930                     attrs: Vec::new(),
1931                     mac: Macro {
1932                         path: expr.path,
1933                         bang_token,
1934                         delimiter,
1935                         tokens,
1936                     },
1937                 }));
1938             }
1939         }
1940 
1941         if allow_struct.0 && input.peek(token::Brace) {
1942             let outer_attrs = Vec::new();
1943             expr_struct_helper(input, outer_attrs, expr.path).map(Expr::Struct)
1944         } else {
1945             Ok(Expr::Path(expr))
1946         }
1947     }
1948 
1949     #[cfg(feature = "full")]
paren_or_tuple(input: ParseStream) -> Result<Expr>1950     fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
1951         let content;
1952         let paren_token = parenthesized!(content in input);
1953         let inner_attrs = content.call(Attribute::parse_inner)?;
1954         if content.is_empty() {
1955             return Ok(Expr::Tuple(ExprTuple {
1956                 attrs: inner_attrs,
1957                 paren_token,
1958                 elems: Punctuated::new(),
1959             }));
1960         }
1961 
1962         let first: Expr = content.parse()?;
1963         if content.is_empty() {
1964             return Ok(Expr::Paren(ExprParen {
1965                 attrs: inner_attrs,
1966                 paren_token,
1967                 expr: Box::new(first),
1968             }));
1969         }
1970 
1971         let mut elems = Punctuated::new();
1972         elems.push_value(first);
1973         while !content.is_empty() {
1974             let punct = content.parse()?;
1975             elems.push_punct(punct);
1976             if content.is_empty() {
1977                 break;
1978             }
1979             let value = content.parse()?;
1980             elems.push_value(value);
1981         }
1982         Ok(Expr::Tuple(ExprTuple {
1983             attrs: inner_attrs,
1984             paren_token,
1985             elems,
1986         }))
1987     }
1988 
1989     #[cfg(feature = "full")]
array_or_repeat(input: ParseStream) -> Result<Expr>1990     fn array_or_repeat(input: ParseStream) -> Result<Expr> {
1991         let content;
1992         let bracket_token = bracketed!(content in input);
1993         let inner_attrs = content.call(Attribute::parse_inner)?;
1994         if content.is_empty() {
1995             return Ok(Expr::Array(ExprArray {
1996                 attrs: inner_attrs,
1997                 bracket_token,
1998                 elems: Punctuated::new(),
1999             }));
2000         }
2001 
2002         let first: Expr = content.parse()?;
2003         if content.is_empty() || content.peek(Token![,]) {
2004             let mut elems = Punctuated::new();
2005             elems.push_value(first);
2006             while !content.is_empty() {
2007                 let punct = content.parse()?;
2008                 elems.push_punct(punct);
2009                 if content.is_empty() {
2010                     break;
2011                 }
2012                 let value = content.parse()?;
2013                 elems.push_value(value);
2014             }
2015             Ok(Expr::Array(ExprArray {
2016                 attrs: inner_attrs,
2017                 bracket_token,
2018                 elems,
2019             }))
2020         } else if content.peek(Token![;]) {
2021             let semi_token: Token![;] = content.parse()?;
2022             let len: Expr = content.parse()?;
2023             Ok(Expr::Repeat(ExprRepeat {
2024                 attrs: inner_attrs,
2025                 bracket_token,
2026                 expr: Box::new(first),
2027                 semi_token,
2028                 len: Box::new(len),
2029             }))
2030         } else {
2031             Err(content.error("expected `,` or `;`"))
2032         }
2033     }
2034 
2035     #[cfg(feature = "full")]
expr_early(input: ParseStream) -> Result<Expr>2036     pub(crate) fn expr_early(input: ParseStream) -> Result<Expr> {
2037         let mut attrs = input.call(expr_attrs)?;
2038         let mut expr = if input.peek(Token![if]) {
2039             Expr::If(input.parse()?)
2040         } else if input.peek(Token![while]) {
2041             Expr::While(input.parse()?)
2042         } else if input.peek(Token![for]) {
2043             Expr::ForLoop(input.parse()?)
2044         } else if input.peek(Token![loop]) {
2045             Expr::Loop(input.parse()?)
2046         } else if input.peek(Token![match]) {
2047             Expr::Match(input.parse()?)
2048         } else if input.peek(Token![try]) && input.peek2(token::Brace) {
2049             Expr::TryBlock(input.call(expr_try_block)?)
2050         } else if input.peek(Token![unsafe]) {
2051             Expr::Unsafe(input.call(expr_unsafe)?)
2052         } else if input.peek(token::Brace) {
2053             Expr::Block(input.call(expr_block)?)
2054         } else {
2055             let allow_struct = AllowStruct(true);
2056             let mut expr = unary_expr(input, allow_struct)?;
2057 
2058             attrs.extend(expr.replace_attrs(Vec::new()));
2059             expr.replace_attrs(attrs);
2060 
2061             return parse_expr(input, expr, allow_struct, Precedence::Any);
2062         };
2063 
2064         if input.peek(Token![.]) && !input.peek(Token![..]) || input.peek(Token![?]) {
2065             expr = trailer_helper(input, expr)?;
2066 
2067             attrs.extend(expr.replace_attrs(Vec::new()));
2068             expr.replace_attrs(attrs);
2069 
2070             let allow_struct = AllowStruct(true);
2071             return parse_expr(input, expr, allow_struct, Precedence::Any);
2072         }
2073 
2074         attrs.extend(expr.replace_attrs(Vec::new()));
2075         expr.replace_attrs(attrs);
2076         Ok(expr)
2077     }
2078 
2079     impl Parse for ExprLit {
parse(input: ParseStream) -> Result<Self>2080         fn parse(input: ParseStream) -> Result<Self> {
2081             Ok(ExprLit {
2082                 attrs: Vec::new(),
2083                 lit: input.parse()?,
2084             })
2085         }
2086     }
2087 
2088     #[cfg(feature = "full")]
expr_group(input: ParseStream) -> Result<ExprGroup>2089     fn expr_group(input: ParseStream) -> Result<ExprGroup> {
2090         let group = crate::group::parse_group(input)?;
2091         Ok(ExprGroup {
2092             attrs: Vec::new(),
2093             group_token: group.token,
2094             expr: group.content.parse()?,
2095         })
2096     }
2097 
2098     #[cfg(not(feature = "full"))]
expr_paren(input: ParseStream) -> Result<ExprParen>2099     fn expr_paren(input: ParseStream) -> Result<ExprParen> {
2100         let content;
2101         Ok(ExprParen {
2102             attrs: Vec::new(),
2103             paren_token: parenthesized!(content in input),
2104             expr: content.parse()?,
2105         })
2106     }
2107 
2108     #[cfg(feature = "full")]
generic_method_argument(input: ParseStream) -> Result<GenericMethodArgument>2109     fn generic_method_argument(input: ParseStream) -> Result<GenericMethodArgument> {
2110         if input.peek(Lit) {
2111             let lit = input.parse()?;
2112             return Ok(GenericMethodArgument::Const(Expr::Lit(lit)));
2113         }
2114 
2115         if input.peek(token::Brace) {
2116             let block = input.call(expr::parsing::expr_block)?;
2117             return Ok(GenericMethodArgument::Const(Expr::Block(block)));
2118         }
2119 
2120         input.parse().map(GenericMethodArgument::Type)
2121     }
2122 
2123     #[cfg(feature = "full")]
expr_let(input: ParseStream) -> Result<ExprLet>2124     fn expr_let(input: ParseStream) -> Result<ExprLet> {
2125         Ok(ExprLet {
2126             attrs: Vec::new(),
2127             let_token: input.parse()?,
2128             pat: pat::parsing::multi_pat_with_leading_vert(input)?,
2129             eq_token: input.parse()?,
2130             expr: Box::new(input.call(Expr::parse_without_eager_brace)?),
2131         })
2132     }
2133 
2134     #[cfg(feature = "full")]
2135     impl Parse for ExprIf {
parse(input: ParseStream) -> Result<Self>2136         fn parse(input: ParseStream) -> Result<Self> {
2137             let attrs = input.call(Attribute::parse_outer)?;
2138             Ok(ExprIf {
2139                 attrs,
2140                 if_token: input.parse()?,
2141                 cond: Box::new(input.call(Expr::parse_without_eager_brace)?),
2142                 then_branch: input.parse()?,
2143                 else_branch: {
2144                     if input.peek(Token![else]) {
2145                         Some(input.call(else_block)?)
2146                     } else {
2147                         None
2148                     }
2149                 },
2150             })
2151         }
2152     }
2153 
2154     #[cfg(feature = "full")]
else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)>2155     fn else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)> {
2156         let else_token: Token![else] = input.parse()?;
2157 
2158         let lookahead = input.lookahead1();
2159         let else_branch = if input.peek(Token![if]) {
2160             input.parse().map(Expr::If)?
2161         } else if input.peek(token::Brace) {
2162             Expr::Block(ExprBlock {
2163                 attrs: Vec::new(),
2164                 label: None,
2165                 block: input.parse()?,
2166             })
2167         } else {
2168             return Err(lookahead.error());
2169         };
2170 
2171         Ok((else_token, Box::new(else_branch)))
2172     }
2173 
2174     #[cfg(feature = "full")]
2175     impl Parse for ExprForLoop {
parse(input: ParseStream) -> Result<Self>2176         fn parse(input: ParseStream) -> Result<Self> {
2177             let outer_attrs = input.call(Attribute::parse_outer)?;
2178             let label: Option<Label> = input.parse()?;
2179             let for_token: Token![for] = input.parse()?;
2180 
2181             let pat = pat::parsing::multi_pat_with_leading_vert(input)?;
2182 
2183             let in_token: Token![in] = input.parse()?;
2184             let expr: Expr = input.call(Expr::parse_without_eager_brace)?;
2185 
2186             let content;
2187             let brace_token = braced!(content in input);
2188             let inner_attrs = content.call(Attribute::parse_inner)?;
2189             let stmts = content.call(Block::parse_within)?;
2190 
2191             Ok(ExprForLoop {
2192                 attrs: private::attrs(outer_attrs, inner_attrs),
2193                 label,
2194                 for_token,
2195                 pat,
2196                 in_token,
2197                 expr: Box::new(expr),
2198                 body: Block { brace_token, stmts },
2199             })
2200         }
2201     }
2202 
2203     #[cfg(feature = "full")]
2204     impl Parse for ExprLoop {
parse(input: ParseStream) -> Result<Self>2205         fn parse(input: ParseStream) -> Result<Self> {
2206             let outer_attrs = input.call(Attribute::parse_outer)?;
2207             let label: Option<Label> = input.parse()?;
2208             let loop_token: Token![loop] = input.parse()?;
2209 
2210             let content;
2211             let brace_token = braced!(content in input);
2212             let inner_attrs = content.call(Attribute::parse_inner)?;
2213             let stmts = content.call(Block::parse_within)?;
2214 
2215             Ok(ExprLoop {
2216                 attrs: private::attrs(outer_attrs, inner_attrs),
2217                 label,
2218                 loop_token,
2219                 body: Block { brace_token, stmts },
2220             })
2221         }
2222     }
2223 
2224     #[cfg(feature = "full")]
2225     impl Parse for ExprMatch {
parse(input: ParseStream) -> Result<Self>2226         fn parse(input: ParseStream) -> Result<Self> {
2227             let outer_attrs = input.call(Attribute::parse_outer)?;
2228             let match_token: Token![match] = input.parse()?;
2229             let expr = Expr::parse_without_eager_brace(input)?;
2230 
2231             let content;
2232             let brace_token = braced!(content in input);
2233             let inner_attrs = content.call(Attribute::parse_inner)?;
2234 
2235             let mut arms = Vec::new();
2236             while !content.is_empty() {
2237                 arms.push(content.call(Arm::parse)?);
2238             }
2239 
2240             Ok(ExprMatch {
2241                 attrs: private::attrs(outer_attrs, inner_attrs),
2242                 match_token,
2243                 expr: Box::new(expr),
2244                 brace_token,
2245                 arms,
2246             })
2247         }
2248     }
2249 
2250     macro_rules! impl_by_parsing_expr {
2251         (
2252             $(
2253                 $expr_type:ty, $variant:ident, $msg:expr,
2254             )*
2255         ) => {
2256             $(
2257                 #[cfg(all(feature = "full", feature = "printing"))]
2258                 impl Parse for $expr_type {
2259                     fn parse(input: ParseStream) -> Result<Self> {
2260                         let mut expr: Expr = input.parse()?;
2261                         loop {
2262                             match expr {
2263                                 Expr::$variant(inner) => return Ok(inner),
2264                                 Expr::Group(next) => expr = *next.expr,
2265                                 _ => return Err(Error::new_spanned(expr, $msg)),
2266                             }
2267                         }
2268                     }
2269                 }
2270             )*
2271         };
2272     }
2273 
2274     impl_by_parsing_expr! {
2275         ExprBox, Box, "expected box expression",
2276         ExprArray, Array, "expected slice literal expression",
2277         ExprCall, Call, "expected function call expression",
2278         ExprMethodCall, MethodCall, "expected method call expression",
2279         ExprTuple, Tuple, "expected tuple expression",
2280         ExprBinary, Binary, "expected binary operation",
2281         ExprUnary, Unary, "expected unary operation",
2282         ExprCast, Cast, "expected cast expression",
2283         ExprType, Type, "expected type ascription expression",
2284         ExprLet, Let, "expected let guard",
2285         ExprClosure, Closure, "expected closure expression",
2286         ExprUnsafe, Unsafe, "expected unsafe block",
2287         ExprBlock, Block, "expected blocked scope",
2288         ExprAssign, Assign, "expected assignment expression",
2289         ExprAssignOp, AssignOp, "expected compound assignment expression",
2290         ExprField, Field, "expected struct field access",
2291         ExprIndex, Index, "expected indexing expression",
2292         ExprRange, Range, "expected range expression",
2293         ExprReference, Reference, "expected referencing operation",
2294         ExprBreak, Break, "expected break expression",
2295         ExprContinue, Continue, "expected continue expression",
2296         ExprReturn, Return, "expected return expression",
2297         ExprMacro, Macro, "expected macro invocation expression",
2298         ExprStruct, Struct, "expected struct literal expression",
2299         ExprRepeat, Repeat, "expected array literal constructed from one repeated element",
2300         ExprParen, Paren, "expected parenthesized expression",
2301         ExprTry, Try, "expected try expression",
2302         ExprAsync, Async, "expected async block",
2303         ExprTryBlock, TryBlock, "expected try block",
2304         ExprYield, Yield, "expected yield expression",
2305     }
2306 
2307     #[cfg(feature = "full")]
expr_try_block(input: ParseStream) -> Result<ExprTryBlock>2308     fn expr_try_block(input: ParseStream) -> Result<ExprTryBlock> {
2309         Ok(ExprTryBlock {
2310             attrs: Vec::new(),
2311             try_token: input.parse()?,
2312             block: input.parse()?,
2313         })
2314     }
2315 
2316     #[cfg(feature = "full")]
expr_yield(input: ParseStream) -> Result<ExprYield>2317     fn expr_yield(input: ParseStream) -> Result<ExprYield> {
2318         Ok(ExprYield {
2319             attrs: Vec::new(),
2320             yield_token: input.parse()?,
2321             expr: {
2322                 if !input.is_empty() && !input.peek(Token![,]) && !input.peek(Token![;]) {
2323                     Some(input.parse()?)
2324                 } else {
2325                     None
2326                 }
2327             },
2328         })
2329     }
2330 
2331     #[cfg(feature = "full")]
expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure>2332     fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
2333         let asyncness: Option<Token![async]> = input.parse()?;
2334         let movability: Option<Token![static]> = if asyncness.is_none() {
2335             input.parse()?
2336         } else {
2337             None
2338         };
2339         let capture: Option<Token![move]> = input.parse()?;
2340         let or1_token: Token![|] = input.parse()?;
2341 
2342         let mut inputs = Punctuated::new();
2343         loop {
2344             if input.peek(Token![|]) {
2345                 break;
2346             }
2347             let value = closure_arg(input)?;
2348             inputs.push_value(value);
2349             if input.peek(Token![|]) {
2350                 break;
2351             }
2352             let punct: Token![,] = input.parse()?;
2353             inputs.push_punct(punct);
2354         }
2355 
2356         let or2_token: Token![|] = input.parse()?;
2357 
2358         let (output, body) = if input.peek(Token![->]) {
2359             let arrow_token: Token![->] = input.parse()?;
2360             let ty: Type = input.parse()?;
2361             let body: Block = input.parse()?;
2362             let output = ReturnType::Type(arrow_token, Box::new(ty));
2363             let block = Expr::Block(ExprBlock {
2364                 attrs: Vec::new(),
2365                 label: None,
2366                 block: body,
2367             });
2368             (output, block)
2369         } else {
2370             let body = ambiguous_expr(input, allow_struct)?;
2371             (ReturnType::Default, body)
2372         };
2373 
2374         Ok(ExprClosure {
2375             attrs: Vec::new(),
2376             asyncness,
2377             movability,
2378             capture,
2379             or1_token,
2380             inputs,
2381             or2_token,
2382             output,
2383             body: Box::new(body),
2384         })
2385     }
2386 
2387     #[cfg(feature = "full")]
expr_async(input: ParseStream) -> Result<ExprAsync>2388     fn expr_async(input: ParseStream) -> Result<ExprAsync> {
2389         Ok(ExprAsync {
2390             attrs: Vec::new(),
2391             async_token: input.parse()?,
2392             capture: input.parse()?,
2393             block: input.parse()?,
2394         })
2395     }
2396 
2397     #[cfg(feature = "full")]
closure_arg(input: ParseStream) -> Result<Pat>2398     fn closure_arg(input: ParseStream) -> Result<Pat> {
2399         let attrs = input.call(Attribute::parse_outer)?;
2400         let mut pat: Pat = input.parse()?;
2401 
2402         if input.peek(Token![:]) {
2403             Ok(Pat::Type(PatType {
2404                 attrs,
2405                 pat: Box::new(pat),
2406                 colon_token: input.parse()?,
2407                 ty: input.parse()?,
2408             }))
2409         } else {
2410             match &mut pat {
2411                 Pat::Box(pat) => pat.attrs = attrs,
2412                 Pat::Ident(pat) => pat.attrs = attrs,
2413                 Pat::Lit(pat) => pat.attrs = attrs,
2414                 Pat::Macro(pat) => pat.attrs = attrs,
2415                 Pat::Or(pat) => pat.attrs = attrs,
2416                 Pat::Path(pat) => pat.attrs = attrs,
2417                 Pat::Range(pat) => pat.attrs = attrs,
2418                 Pat::Reference(pat) => pat.attrs = attrs,
2419                 Pat::Rest(pat) => pat.attrs = attrs,
2420                 Pat::Slice(pat) => pat.attrs = attrs,
2421                 Pat::Struct(pat) => pat.attrs = attrs,
2422                 Pat::Tuple(pat) => pat.attrs = attrs,
2423                 Pat::TupleStruct(pat) => pat.attrs = attrs,
2424                 Pat::Type(_) => unreachable!(),
2425                 Pat::Verbatim(_) => {}
2426                 Pat::Wild(pat) => pat.attrs = attrs,
2427                 Pat::__Nonexhaustive => unreachable!(),
2428             }
2429             Ok(pat)
2430         }
2431     }
2432 
2433     #[cfg(feature = "full")]
2434     impl Parse for ExprWhile {
parse(input: ParseStream) -> Result<Self>2435         fn parse(input: ParseStream) -> Result<Self> {
2436             let outer_attrs = input.call(Attribute::parse_outer)?;
2437             let label: Option<Label> = input.parse()?;
2438             let while_token: Token![while] = input.parse()?;
2439             let cond = Expr::parse_without_eager_brace(input)?;
2440 
2441             let content;
2442             let brace_token = braced!(content in input);
2443             let inner_attrs = content.call(Attribute::parse_inner)?;
2444             let stmts = content.call(Block::parse_within)?;
2445 
2446             Ok(ExprWhile {
2447                 attrs: private::attrs(outer_attrs, inner_attrs),
2448                 label,
2449                 while_token,
2450                 cond: Box::new(cond),
2451                 body: Block { brace_token, stmts },
2452             })
2453         }
2454     }
2455 
2456     #[cfg(feature = "full")]
2457     impl Parse for Label {
parse(input: ParseStream) -> Result<Self>2458         fn parse(input: ParseStream) -> Result<Self> {
2459             Ok(Label {
2460                 name: input.parse()?,
2461                 colon_token: input.parse()?,
2462             })
2463         }
2464     }
2465 
2466     #[cfg(feature = "full")]
2467     impl Parse for Option<Label> {
parse(input: ParseStream) -> Result<Self>2468         fn parse(input: ParseStream) -> Result<Self> {
2469             if input.peek(Lifetime) {
2470                 input.parse().map(Some)
2471             } else {
2472                 Ok(None)
2473             }
2474         }
2475     }
2476 
2477     #[cfg(feature = "full")]
expr_continue(input: ParseStream) -> Result<ExprContinue>2478     fn expr_continue(input: ParseStream) -> Result<ExprContinue> {
2479         Ok(ExprContinue {
2480             attrs: Vec::new(),
2481             continue_token: input.parse()?,
2482             label: input.parse()?,
2483         })
2484     }
2485 
2486     #[cfg(feature = "full")]
expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak>2487     fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
2488         Ok(ExprBreak {
2489             attrs: Vec::new(),
2490             break_token: input.parse()?,
2491             label: input.parse()?,
2492             expr: {
2493                 if input.is_empty()
2494                     || input.peek(Token![,])
2495                     || input.peek(Token![;])
2496                     || !allow_struct.0 && input.peek(token::Brace)
2497                 {
2498                     None
2499                 } else {
2500                     let expr = ambiguous_expr(input, allow_struct)?;
2501                     Some(Box::new(expr))
2502                 }
2503             },
2504         })
2505     }
2506 
2507     #[cfg(feature = "full")]
expr_ret(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn>2508     fn expr_ret(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn> {
2509         Ok(ExprReturn {
2510             attrs: Vec::new(),
2511             return_token: input.parse()?,
2512             expr: {
2513                 if input.is_empty() || input.peek(Token![,]) || input.peek(Token![;]) {
2514                     None
2515                 } else {
2516                     // NOTE: return is greedy and eats blocks after it even when in a
2517                     // position where structs are not allowed, such as in if statement
2518                     // conditions. For example:
2519                     //
2520                     // if return { println!("A") } {} // Prints "A"
2521                     let expr = ambiguous_expr(input, allow_struct)?;
2522                     Some(Box::new(expr))
2523                 }
2524             },
2525         })
2526     }
2527 
2528     #[cfg(feature = "full")]
2529     impl Parse for FieldValue {
parse(input: ParseStream) -> Result<Self>2530         fn parse(input: ParseStream) -> Result<Self> {
2531             let attrs = input.call(Attribute::parse_outer)?;
2532             let member: Member = input.parse()?;
2533             let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() {
2534                 let colon_token: Token![:] = input.parse()?;
2535                 let value: Expr = input.parse()?;
2536                 (Some(colon_token), value)
2537             } else if let Member::Named(ident) = &member {
2538                 let value = Expr::Path(ExprPath {
2539                     attrs: Vec::new(),
2540                     qself: None,
2541                     path: Path::from(ident.clone()),
2542                 });
2543                 (None, value)
2544             } else {
2545                 unreachable!()
2546             };
2547 
2548             Ok(FieldValue {
2549                 attrs,
2550                 member,
2551                 colon_token,
2552                 expr: value,
2553             })
2554         }
2555     }
2556 
2557     #[cfg(feature = "full")]
expr_struct_helper( input: ParseStream, outer_attrs: Vec<Attribute>, path: Path, ) -> Result<ExprStruct>2558     fn expr_struct_helper(
2559         input: ParseStream,
2560         outer_attrs: Vec<Attribute>,
2561         path: Path,
2562     ) -> Result<ExprStruct> {
2563         let content;
2564         let brace_token = braced!(content in input);
2565         let inner_attrs = content.call(Attribute::parse_inner)?;
2566         let attrs = private::attrs(outer_attrs, inner_attrs);
2567 
2568         let mut fields = Punctuated::new();
2569         while !content.is_empty() {
2570             if content.peek(Token![..]) {
2571                 return Ok(ExprStruct {
2572                     attrs,
2573                     brace_token,
2574                     path,
2575                     fields,
2576                     dot2_token: Some(content.parse()?),
2577                     rest: Some(Box::new(content.parse()?)),
2578                 });
2579             }
2580 
2581             fields.push(content.parse()?);
2582             if content.is_empty() {
2583                 break;
2584             }
2585             let punct: Token![,] = content.parse()?;
2586             fields.push_punct(punct);
2587         }
2588 
2589         Ok(ExprStruct {
2590             attrs,
2591             brace_token,
2592             path,
2593             fields,
2594             dot2_token: None,
2595             rest: None,
2596         })
2597     }
2598 
2599     #[cfg(feature = "full")]
expr_unsafe(input: ParseStream) -> Result<ExprUnsafe>2600     fn expr_unsafe(input: ParseStream) -> Result<ExprUnsafe> {
2601         let unsafe_token: Token![unsafe] = input.parse()?;
2602 
2603         let content;
2604         let brace_token = braced!(content in input);
2605         let inner_attrs = content.call(Attribute::parse_inner)?;
2606         let stmts = content.call(Block::parse_within)?;
2607 
2608         Ok(ExprUnsafe {
2609             attrs: inner_attrs,
2610             unsafe_token,
2611             block: Block { brace_token, stmts },
2612         })
2613     }
2614 
2615     #[cfg(feature = "full")]
expr_block(input: ParseStream) -> Result<ExprBlock>2616     pub fn expr_block(input: ParseStream) -> Result<ExprBlock> {
2617         let label: Option<Label> = input.parse()?;
2618 
2619         let content;
2620         let brace_token = braced!(content in input);
2621         let inner_attrs = content.call(Attribute::parse_inner)?;
2622         let stmts = content.call(Block::parse_within)?;
2623 
2624         Ok(ExprBlock {
2625             attrs: inner_attrs,
2626             label,
2627             block: Block { brace_token, stmts },
2628         })
2629     }
2630 
2631     #[cfg(feature = "full")]
expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange>2632     fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
2633         Ok(ExprRange {
2634             attrs: Vec::new(),
2635             from: None,
2636             limits: input.parse()?,
2637             to: {
2638                 if input.is_empty()
2639                     || input.peek(Token![,])
2640                     || input.peek(Token![;])
2641                     || !allow_struct.0 && input.peek(token::Brace)
2642                 {
2643                     None
2644                 } else {
2645                     let to = ambiguous_expr(input, allow_struct)?;
2646                     Some(Box::new(to))
2647                 }
2648             },
2649         })
2650     }
2651 
2652     #[cfg(feature = "full")]
2653     impl Parse for RangeLimits {
parse(input: ParseStream) -> Result<Self>2654         fn parse(input: ParseStream) -> Result<Self> {
2655             let lookahead = input.lookahead1();
2656             if lookahead.peek(Token![..=]) {
2657                 input.parse().map(RangeLimits::Closed)
2658             } else if lookahead.peek(Token![...]) {
2659                 let dot3: Token![...] = input.parse()?;
2660                 Ok(RangeLimits::Closed(Token![..=](dot3.spans)))
2661             } else if lookahead.peek(Token![..]) {
2662                 input.parse().map(RangeLimits::HalfOpen)
2663             } else {
2664                 Err(lookahead.error())
2665             }
2666         }
2667     }
2668 
2669     impl Parse for ExprPath {
parse(input: ParseStream) -> Result<Self>2670         fn parse(input: ParseStream) -> Result<Self> {
2671             #[cfg(not(feature = "full"))]
2672             let attrs = Vec::new();
2673             #[cfg(feature = "full")]
2674             let attrs = input.call(Attribute::parse_outer)?;
2675 
2676             let (qself, path) = path::parsing::qpath(input, true)?;
2677 
2678             Ok(ExprPath { attrs, qself, path })
2679         }
2680     }
2681 
2682     impl Parse for Member {
parse(input: ParseStream) -> Result<Self>2683         fn parse(input: ParseStream) -> Result<Self> {
2684             if input.peek(Ident) {
2685                 input.parse().map(Member::Named)
2686             } else if input.peek(LitInt) {
2687                 input.parse().map(Member::Unnamed)
2688             } else {
2689                 Err(input.error("expected identifier or integer"))
2690             }
2691         }
2692     }
2693 
2694     #[cfg(feature = "full")]
2695     impl Parse for Arm {
parse(input: ParseStream) -> Result<Arm>2696         fn parse(input: ParseStream) -> Result<Arm> {
2697             let requires_comma;
2698             Ok(Arm {
2699                 attrs: input.call(Attribute::parse_outer)?,
2700                 pat: pat::parsing::multi_pat_with_leading_vert(input)?,
2701                 guard: {
2702                     if input.peek(Token![if]) {
2703                         let if_token: Token![if] = input.parse()?;
2704                         let guard: Expr = input.parse()?;
2705                         Some((if_token, Box::new(guard)))
2706                     } else {
2707                         None
2708                     }
2709                 },
2710                 fat_arrow_token: input.parse()?,
2711                 body: {
2712                     let body = input.call(expr_early)?;
2713                     requires_comma = requires_terminator(&body);
2714                     Box::new(body)
2715                 },
2716                 comma: {
2717                     if requires_comma && !input.is_empty() {
2718                         Some(input.parse()?)
2719                     } else {
2720                         input.parse()?
2721                     }
2722                 },
2723             })
2724         }
2725     }
2726 
2727     impl Parse for Index {
parse(input: ParseStream) -> Result<Self>2728         fn parse(input: ParseStream) -> Result<Self> {
2729             let lit: LitInt = input.parse()?;
2730             if lit.suffix().is_empty() {
2731                 Ok(Index {
2732                     index: lit
2733                         .base10_digits()
2734                         .parse()
2735                         .map_err(|err| Error::new(lit.span(), err))?,
2736                     span: lit.span(),
2737                 })
2738             } else {
2739                 Err(Error::new(lit.span(), "expected unsuffixed integer"))
2740             }
2741         }
2742     }
2743 
multi_index(e: &mut Expr, dot_token: &mut Token![.], float: LitFloat) -> Result<bool>2744     fn multi_index(e: &mut Expr, dot_token: &mut Token![.], float: LitFloat) -> Result<bool> {
2745         let mut float_repr = float.to_string();
2746         let trailing_dot = float_repr.ends_with('.');
2747         if trailing_dot {
2748             float_repr.truncate(float_repr.len() - 1);
2749         }
2750         for part in float_repr.split('.') {
2751             let index = crate::parse_str(part).map_err(|err| Error::new(float.span(), err))?;
2752             let base = mem::replace(e, Expr::__Nonexhaustive);
2753             *e = Expr::Field(ExprField {
2754                 attrs: Vec::new(),
2755                 base: Box::new(base),
2756                 dot_token: Token![.](dot_token.span),
2757                 member: Member::Unnamed(index),
2758             });
2759             *dot_token = Token![.](float.span());
2760         }
2761         Ok(!trailing_dot)
2762     }
2763 
2764     #[cfg(feature = "full")]
2765     impl Member {
is_named(&self) -> bool2766         fn is_named(&self) -> bool {
2767             match *self {
2768                 Member::Named(_) => true,
2769                 Member::Unnamed(_) => false,
2770             }
2771         }
2772     }
2773 }
2774 
2775 #[cfg(feature = "printing")]
2776 pub(crate) mod printing {
2777     use super::*;
2778 
2779     use proc_macro2::{Literal, TokenStream};
2780     use quote::{ToTokens, TokenStreamExt};
2781 
2782     #[cfg(feature = "full")]
2783     use crate::attr::FilterAttrs;
2784     #[cfg(feature = "full")]
2785     use crate::print::TokensOrDefault;
2786 
2787     // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2788     // before appending it to `TokenStream`.
2789     #[cfg(feature = "full")]
wrap_bare_struct(tokens: &mut TokenStream, e: &Expr)2790     fn wrap_bare_struct(tokens: &mut TokenStream, e: &Expr) {
2791         if let Expr::Struct(_) = *e {
2792             token::Paren::default().surround(tokens, |tokens| {
2793                 e.to_tokens(tokens);
2794             });
2795         } else {
2796             e.to_tokens(tokens);
2797         }
2798     }
2799 
2800     #[cfg(feature = "full")]
outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream)2801     pub(crate) fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
2802         tokens.append_all(attrs.outer());
2803     }
2804 
2805     #[cfg(feature = "full")]
inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream)2806     fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
2807         tokens.append_all(attrs.inner());
2808     }
2809 
2810     #[cfg(not(feature = "full"))]
outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream)2811     pub(crate) fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
2812 
2813     #[cfg(not(feature = "full"))]
inner_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream)2814     fn inner_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
2815 
2816     #[cfg(feature = "full")]
2817     impl ToTokens for ExprBox {
to_tokens(&self, tokens: &mut TokenStream)2818         fn to_tokens(&self, tokens: &mut TokenStream) {
2819             outer_attrs_to_tokens(&self.attrs, tokens);
2820             self.box_token.to_tokens(tokens);
2821             self.expr.to_tokens(tokens);
2822         }
2823     }
2824 
2825     #[cfg(feature = "full")]
2826     impl ToTokens for ExprArray {
to_tokens(&self, tokens: &mut TokenStream)2827         fn to_tokens(&self, tokens: &mut TokenStream) {
2828             outer_attrs_to_tokens(&self.attrs, tokens);
2829             self.bracket_token.surround(tokens, |tokens| {
2830                 inner_attrs_to_tokens(&self.attrs, tokens);
2831                 self.elems.to_tokens(tokens);
2832             })
2833         }
2834     }
2835 
2836     impl ToTokens for ExprCall {
to_tokens(&self, tokens: &mut TokenStream)2837         fn to_tokens(&self, tokens: &mut TokenStream) {
2838             outer_attrs_to_tokens(&self.attrs, tokens);
2839             self.func.to_tokens(tokens);
2840             self.paren_token.surround(tokens, |tokens| {
2841                 self.args.to_tokens(tokens);
2842             })
2843         }
2844     }
2845 
2846     #[cfg(feature = "full")]
2847     impl ToTokens for ExprMethodCall {
to_tokens(&self, tokens: &mut TokenStream)2848         fn to_tokens(&self, tokens: &mut TokenStream) {
2849             outer_attrs_to_tokens(&self.attrs, tokens);
2850             self.receiver.to_tokens(tokens);
2851             self.dot_token.to_tokens(tokens);
2852             self.method.to_tokens(tokens);
2853             self.turbofish.to_tokens(tokens);
2854             self.paren_token.surround(tokens, |tokens| {
2855                 self.args.to_tokens(tokens);
2856             });
2857         }
2858     }
2859 
2860     #[cfg(feature = "full")]
2861     impl ToTokens for MethodTurbofish {
to_tokens(&self, tokens: &mut TokenStream)2862         fn to_tokens(&self, tokens: &mut TokenStream) {
2863             self.colon2_token.to_tokens(tokens);
2864             self.lt_token.to_tokens(tokens);
2865             self.args.to_tokens(tokens);
2866             self.gt_token.to_tokens(tokens);
2867         }
2868     }
2869 
2870     #[cfg(feature = "full")]
2871     impl ToTokens for GenericMethodArgument {
to_tokens(&self, tokens: &mut TokenStream)2872         fn to_tokens(&self, tokens: &mut TokenStream) {
2873             match self {
2874                 GenericMethodArgument::Type(t) => t.to_tokens(tokens),
2875                 GenericMethodArgument::Const(c) => c.to_tokens(tokens),
2876             }
2877         }
2878     }
2879 
2880     #[cfg(feature = "full")]
2881     impl ToTokens for ExprTuple {
to_tokens(&self, tokens: &mut TokenStream)2882         fn to_tokens(&self, tokens: &mut TokenStream) {
2883             outer_attrs_to_tokens(&self.attrs, tokens);
2884             self.paren_token.surround(tokens, |tokens| {
2885                 inner_attrs_to_tokens(&self.attrs, tokens);
2886                 self.elems.to_tokens(tokens);
2887                 // If we only have one argument, we need a trailing comma to
2888                 // distinguish ExprTuple from ExprParen.
2889                 if self.elems.len() == 1 && !self.elems.trailing_punct() {
2890                     <Token![,]>::default().to_tokens(tokens);
2891                 }
2892             })
2893         }
2894     }
2895 
2896     impl ToTokens for ExprBinary {
to_tokens(&self, tokens: &mut TokenStream)2897         fn to_tokens(&self, tokens: &mut TokenStream) {
2898             outer_attrs_to_tokens(&self.attrs, tokens);
2899             self.left.to_tokens(tokens);
2900             self.op.to_tokens(tokens);
2901             self.right.to_tokens(tokens);
2902         }
2903     }
2904 
2905     impl ToTokens for ExprUnary {
to_tokens(&self, tokens: &mut TokenStream)2906         fn to_tokens(&self, tokens: &mut TokenStream) {
2907             outer_attrs_to_tokens(&self.attrs, tokens);
2908             self.op.to_tokens(tokens);
2909             self.expr.to_tokens(tokens);
2910         }
2911     }
2912 
2913     impl ToTokens for ExprLit {
to_tokens(&self, tokens: &mut TokenStream)2914         fn to_tokens(&self, tokens: &mut TokenStream) {
2915             outer_attrs_to_tokens(&self.attrs, tokens);
2916             self.lit.to_tokens(tokens);
2917         }
2918     }
2919 
2920     impl ToTokens for ExprCast {
to_tokens(&self, tokens: &mut TokenStream)2921         fn to_tokens(&self, tokens: &mut TokenStream) {
2922             outer_attrs_to_tokens(&self.attrs, tokens);
2923             self.expr.to_tokens(tokens);
2924             self.as_token.to_tokens(tokens);
2925             self.ty.to_tokens(tokens);
2926         }
2927     }
2928 
2929     #[cfg(feature = "full")]
2930     impl ToTokens for ExprType {
to_tokens(&self, tokens: &mut TokenStream)2931         fn to_tokens(&self, tokens: &mut TokenStream) {
2932             outer_attrs_to_tokens(&self.attrs, tokens);
2933             self.expr.to_tokens(tokens);
2934             self.colon_token.to_tokens(tokens);
2935             self.ty.to_tokens(tokens);
2936         }
2937     }
2938 
2939     #[cfg(feature = "full")]
maybe_wrap_else(tokens: &mut TokenStream, else_: &Option<(Token![else], Box<Expr>)>)2940     fn maybe_wrap_else(tokens: &mut TokenStream, else_: &Option<(Token![else], Box<Expr>)>) {
2941         if let Some((else_token, else_)) = else_ {
2942             else_token.to_tokens(tokens);
2943 
2944             // If we are not one of the valid expressions to exist in an else
2945             // clause, wrap ourselves in a block.
2946             match **else_ {
2947                 Expr::If(_) | Expr::Block(_) => {
2948                     else_.to_tokens(tokens);
2949                 }
2950                 _ => {
2951                     token::Brace::default().surround(tokens, |tokens| {
2952                         else_.to_tokens(tokens);
2953                     });
2954                 }
2955             }
2956         }
2957     }
2958 
2959     #[cfg(feature = "full")]
2960     impl ToTokens for ExprLet {
to_tokens(&self, tokens: &mut TokenStream)2961         fn to_tokens(&self, tokens: &mut TokenStream) {
2962             outer_attrs_to_tokens(&self.attrs, tokens);
2963             self.let_token.to_tokens(tokens);
2964             self.pat.to_tokens(tokens);
2965             self.eq_token.to_tokens(tokens);
2966             wrap_bare_struct(tokens, &self.expr);
2967         }
2968     }
2969 
2970     #[cfg(feature = "full")]
2971     impl ToTokens for ExprIf {
to_tokens(&self, tokens: &mut TokenStream)2972         fn to_tokens(&self, tokens: &mut TokenStream) {
2973             outer_attrs_to_tokens(&self.attrs, tokens);
2974             self.if_token.to_tokens(tokens);
2975             wrap_bare_struct(tokens, &self.cond);
2976             self.then_branch.to_tokens(tokens);
2977             maybe_wrap_else(tokens, &self.else_branch);
2978         }
2979     }
2980 
2981     #[cfg(feature = "full")]
2982     impl ToTokens for ExprWhile {
to_tokens(&self, tokens: &mut TokenStream)2983         fn to_tokens(&self, tokens: &mut TokenStream) {
2984             outer_attrs_to_tokens(&self.attrs, tokens);
2985             self.label.to_tokens(tokens);
2986             self.while_token.to_tokens(tokens);
2987             wrap_bare_struct(tokens, &self.cond);
2988             self.body.brace_token.surround(tokens, |tokens| {
2989                 inner_attrs_to_tokens(&self.attrs, tokens);
2990                 tokens.append_all(&self.body.stmts);
2991             });
2992         }
2993     }
2994 
2995     #[cfg(feature = "full")]
2996     impl ToTokens for ExprForLoop {
to_tokens(&self, tokens: &mut TokenStream)2997         fn to_tokens(&self, tokens: &mut TokenStream) {
2998             outer_attrs_to_tokens(&self.attrs, tokens);
2999             self.label.to_tokens(tokens);
3000             self.for_token.to_tokens(tokens);
3001             self.pat.to_tokens(tokens);
3002             self.in_token.to_tokens(tokens);
3003             wrap_bare_struct(tokens, &self.expr);
3004             self.body.brace_token.surround(tokens, |tokens| {
3005                 inner_attrs_to_tokens(&self.attrs, tokens);
3006                 tokens.append_all(&self.body.stmts);
3007             });
3008         }
3009     }
3010 
3011     #[cfg(feature = "full")]
3012     impl ToTokens for ExprLoop {
to_tokens(&self, tokens: &mut TokenStream)3013         fn to_tokens(&self, tokens: &mut TokenStream) {
3014             outer_attrs_to_tokens(&self.attrs, tokens);
3015             self.label.to_tokens(tokens);
3016             self.loop_token.to_tokens(tokens);
3017             self.body.brace_token.surround(tokens, |tokens| {
3018                 inner_attrs_to_tokens(&self.attrs, tokens);
3019                 tokens.append_all(&self.body.stmts);
3020             });
3021         }
3022     }
3023 
3024     #[cfg(feature = "full")]
3025     impl ToTokens for ExprMatch {
to_tokens(&self, tokens: &mut TokenStream)3026         fn to_tokens(&self, tokens: &mut TokenStream) {
3027             outer_attrs_to_tokens(&self.attrs, tokens);
3028             self.match_token.to_tokens(tokens);
3029             wrap_bare_struct(tokens, &self.expr);
3030             self.brace_token.surround(tokens, |tokens| {
3031                 inner_attrs_to_tokens(&self.attrs, tokens);
3032                 for (i, arm) in self.arms.iter().enumerate() {
3033                     arm.to_tokens(tokens);
3034                     // Ensure that we have a comma after a non-block arm, except
3035                     // for the last one.
3036                     let is_last = i == self.arms.len() - 1;
3037                     if !is_last && requires_terminator(&arm.body) && arm.comma.is_none() {
3038                         <Token![,]>::default().to_tokens(tokens);
3039                     }
3040                 }
3041             });
3042         }
3043     }
3044 
3045     #[cfg(feature = "full")]
3046     impl ToTokens for ExprAsync {
to_tokens(&self, tokens: &mut TokenStream)3047         fn to_tokens(&self, tokens: &mut TokenStream) {
3048             outer_attrs_to_tokens(&self.attrs, tokens);
3049             self.async_token.to_tokens(tokens);
3050             self.capture.to_tokens(tokens);
3051             self.block.to_tokens(tokens);
3052         }
3053     }
3054 
3055     #[cfg(feature = "full")]
3056     impl ToTokens for ExprAwait {
to_tokens(&self, tokens: &mut TokenStream)3057         fn to_tokens(&self, tokens: &mut TokenStream) {
3058             outer_attrs_to_tokens(&self.attrs, tokens);
3059             self.base.to_tokens(tokens);
3060             self.dot_token.to_tokens(tokens);
3061             self.await_token.to_tokens(tokens);
3062         }
3063     }
3064 
3065     #[cfg(feature = "full")]
3066     impl ToTokens for ExprTryBlock {
to_tokens(&self, tokens: &mut TokenStream)3067         fn to_tokens(&self, tokens: &mut TokenStream) {
3068             outer_attrs_to_tokens(&self.attrs, tokens);
3069             self.try_token.to_tokens(tokens);
3070             self.block.to_tokens(tokens);
3071         }
3072     }
3073 
3074     #[cfg(feature = "full")]
3075     impl ToTokens for ExprYield {
to_tokens(&self, tokens: &mut TokenStream)3076         fn to_tokens(&self, tokens: &mut TokenStream) {
3077             outer_attrs_to_tokens(&self.attrs, tokens);
3078             self.yield_token.to_tokens(tokens);
3079             self.expr.to_tokens(tokens);
3080         }
3081     }
3082 
3083     #[cfg(feature = "full")]
3084     impl ToTokens for ExprClosure {
to_tokens(&self, tokens: &mut TokenStream)3085         fn to_tokens(&self, tokens: &mut TokenStream) {
3086             outer_attrs_to_tokens(&self.attrs, tokens);
3087             self.asyncness.to_tokens(tokens);
3088             self.movability.to_tokens(tokens);
3089             self.capture.to_tokens(tokens);
3090             self.or1_token.to_tokens(tokens);
3091             self.inputs.to_tokens(tokens);
3092             self.or2_token.to_tokens(tokens);
3093             self.output.to_tokens(tokens);
3094             self.body.to_tokens(tokens);
3095         }
3096     }
3097 
3098     #[cfg(feature = "full")]
3099     impl ToTokens for ExprUnsafe {
to_tokens(&self, tokens: &mut TokenStream)3100         fn to_tokens(&self, tokens: &mut TokenStream) {
3101             outer_attrs_to_tokens(&self.attrs, tokens);
3102             self.unsafe_token.to_tokens(tokens);
3103             self.block.brace_token.surround(tokens, |tokens| {
3104                 inner_attrs_to_tokens(&self.attrs, tokens);
3105                 tokens.append_all(&self.block.stmts);
3106             });
3107         }
3108     }
3109 
3110     #[cfg(feature = "full")]
3111     impl ToTokens for ExprBlock {
to_tokens(&self, tokens: &mut TokenStream)3112         fn to_tokens(&self, tokens: &mut TokenStream) {
3113             outer_attrs_to_tokens(&self.attrs, tokens);
3114             self.label.to_tokens(tokens);
3115             self.block.brace_token.surround(tokens, |tokens| {
3116                 inner_attrs_to_tokens(&self.attrs, tokens);
3117                 tokens.append_all(&self.block.stmts);
3118             });
3119         }
3120     }
3121 
3122     #[cfg(feature = "full")]
3123     impl ToTokens for ExprAssign {
to_tokens(&self, tokens: &mut TokenStream)3124         fn to_tokens(&self, tokens: &mut TokenStream) {
3125             outer_attrs_to_tokens(&self.attrs, tokens);
3126             self.left.to_tokens(tokens);
3127             self.eq_token.to_tokens(tokens);
3128             self.right.to_tokens(tokens);
3129         }
3130     }
3131 
3132     #[cfg(feature = "full")]
3133     impl ToTokens for ExprAssignOp {
to_tokens(&self, tokens: &mut TokenStream)3134         fn to_tokens(&self, tokens: &mut TokenStream) {
3135             outer_attrs_to_tokens(&self.attrs, tokens);
3136             self.left.to_tokens(tokens);
3137             self.op.to_tokens(tokens);
3138             self.right.to_tokens(tokens);
3139         }
3140     }
3141 
3142     impl ToTokens for ExprField {
to_tokens(&self, tokens: &mut TokenStream)3143         fn to_tokens(&self, tokens: &mut TokenStream) {
3144             outer_attrs_to_tokens(&self.attrs, tokens);
3145             self.base.to_tokens(tokens);
3146             self.dot_token.to_tokens(tokens);
3147             self.member.to_tokens(tokens);
3148         }
3149     }
3150 
3151     impl ToTokens for Member {
to_tokens(&self, tokens: &mut TokenStream)3152         fn to_tokens(&self, tokens: &mut TokenStream) {
3153             match self {
3154                 Member::Named(ident) => ident.to_tokens(tokens),
3155                 Member::Unnamed(index) => index.to_tokens(tokens),
3156             }
3157         }
3158     }
3159 
3160     impl ToTokens for Index {
to_tokens(&self, tokens: &mut TokenStream)3161         fn to_tokens(&self, tokens: &mut TokenStream) {
3162             let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
3163             lit.set_span(self.span);
3164             tokens.append(lit);
3165         }
3166     }
3167 
3168     impl ToTokens for ExprIndex {
to_tokens(&self, tokens: &mut TokenStream)3169         fn to_tokens(&self, tokens: &mut TokenStream) {
3170             outer_attrs_to_tokens(&self.attrs, tokens);
3171             self.expr.to_tokens(tokens);
3172             self.bracket_token.surround(tokens, |tokens| {
3173                 self.index.to_tokens(tokens);
3174             });
3175         }
3176     }
3177 
3178     #[cfg(feature = "full")]
3179     impl ToTokens for ExprRange {
to_tokens(&self, tokens: &mut TokenStream)3180         fn to_tokens(&self, tokens: &mut TokenStream) {
3181             outer_attrs_to_tokens(&self.attrs, tokens);
3182             self.from.to_tokens(tokens);
3183             match &self.limits {
3184                 RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
3185                 RangeLimits::Closed(t) => t.to_tokens(tokens),
3186             }
3187             self.to.to_tokens(tokens);
3188         }
3189     }
3190 
3191     impl ToTokens for ExprPath {
to_tokens(&self, tokens: &mut TokenStream)3192         fn to_tokens(&self, tokens: &mut TokenStream) {
3193             outer_attrs_to_tokens(&self.attrs, tokens);
3194             private::print_path(tokens, &self.qself, &self.path);
3195         }
3196     }
3197 
3198     #[cfg(feature = "full")]
3199     impl ToTokens for ExprReference {
to_tokens(&self, tokens: &mut TokenStream)3200         fn to_tokens(&self, tokens: &mut TokenStream) {
3201             outer_attrs_to_tokens(&self.attrs, tokens);
3202             self.and_token.to_tokens(tokens);
3203             self.mutability.to_tokens(tokens);
3204             self.expr.to_tokens(tokens);
3205         }
3206     }
3207 
3208     #[cfg(feature = "full")]
3209     impl ToTokens for ExprBreak {
to_tokens(&self, tokens: &mut TokenStream)3210         fn to_tokens(&self, tokens: &mut TokenStream) {
3211             outer_attrs_to_tokens(&self.attrs, tokens);
3212             self.break_token.to_tokens(tokens);
3213             self.label.to_tokens(tokens);
3214             self.expr.to_tokens(tokens);
3215         }
3216     }
3217 
3218     #[cfg(feature = "full")]
3219     impl ToTokens for ExprContinue {
to_tokens(&self, tokens: &mut TokenStream)3220         fn to_tokens(&self, tokens: &mut TokenStream) {
3221             outer_attrs_to_tokens(&self.attrs, tokens);
3222             self.continue_token.to_tokens(tokens);
3223             self.label.to_tokens(tokens);
3224         }
3225     }
3226 
3227     #[cfg(feature = "full")]
3228     impl ToTokens for ExprReturn {
to_tokens(&self, tokens: &mut TokenStream)3229         fn to_tokens(&self, tokens: &mut TokenStream) {
3230             outer_attrs_to_tokens(&self.attrs, tokens);
3231             self.return_token.to_tokens(tokens);
3232             self.expr.to_tokens(tokens);
3233         }
3234     }
3235 
3236     #[cfg(feature = "full")]
3237     impl ToTokens for ExprMacro {
to_tokens(&self, tokens: &mut TokenStream)3238         fn to_tokens(&self, tokens: &mut TokenStream) {
3239             outer_attrs_to_tokens(&self.attrs, tokens);
3240             self.mac.to_tokens(tokens);
3241         }
3242     }
3243 
3244     #[cfg(feature = "full")]
3245     impl ToTokens for ExprStruct {
to_tokens(&self, tokens: &mut TokenStream)3246         fn to_tokens(&self, tokens: &mut TokenStream) {
3247             outer_attrs_to_tokens(&self.attrs, tokens);
3248             self.path.to_tokens(tokens);
3249             self.brace_token.surround(tokens, |tokens| {
3250                 inner_attrs_to_tokens(&self.attrs, tokens);
3251                 self.fields.to_tokens(tokens);
3252                 if self.rest.is_some() {
3253                     TokensOrDefault(&self.dot2_token).to_tokens(tokens);
3254                     self.rest.to_tokens(tokens);
3255                 }
3256             })
3257         }
3258     }
3259 
3260     #[cfg(feature = "full")]
3261     impl ToTokens for ExprRepeat {
to_tokens(&self, tokens: &mut TokenStream)3262         fn to_tokens(&self, tokens: &mut TokenStream) {
3263             outer_attrs_to_tokens(&self.attrs, tokens);
3264             self.bracket_token.surround(tokens, |tokens| {
3265                 inner_attrs_to_tokens(&self.attrs, tokens);
3266                 self.expr.to_tokens(tokens);
3267                 self.semi_token.to_tokens(tokens);
3268                 self.len.to_tokens(tokens);
3269             })
3270         }
3271     }
3272 
3273     #[cfg(feature = "full")]
3274     impl ToTokens for ExprGroup {
to_tokens(&self, tokens: &mut TokenStream)3275         fn to_tokens(&self, tokens: &mut TokenStream) {
3276             outer_attrs_to_tokens(&self.attrs, tokens);
3277             self.group_token.surround(tokens, |tokens| {
3278                 self.expr.to_tokens(tokens);
3279             });
3280         }
3281     }
3282 
3283     impl ToTokens for ExprParen {
to_tokens(&self, tokens: &mut TokenStream)3284         fn to_tokens(&self, tokens: &mut TokenStream) {
3285             outer_attrs_to_tokens(&self.attrs, tokens);
3286             self.paren_token.surround(tokens, |tokens| {
3287                 inner_attrs_to_tokens(&self.attrs, tokens);
3288                 self.expr.to_tokens(tokens);
3289             });
3290         }
3291     }
3292 
3293     #[cfg(feature = "full")]
3294     impl ToTokens for ExprTry {
to_tokens(&self, tokens: &mut TokenStream)3295         fn to_tokens(&self, tokens: &mut TokenStream) {
3296             outer_attrs_to_tokens(&self.attrs, tokens);
3297             self.expr.to_tokens(tokens);
3298             self.question_token.to_tokens(tokens);
3299         }
3300     }
3301 
3302     #[cfg(feature = "full")]
3303     impl ToTokens for Label {
to_tokens(&self, tokens: &mut TokenStream)3304         fn to_tokens(&self, tokens: &mut TokenStream) {
3305             self.name.to_tokens(tokens);
3306             self.colon_token.to_tokens(tokens);
3307         }
3308     }
3309 
3310     #[cfg(feature = "full")]
3311     impl ToTokens for FieldValue {
to_tokens(&self, tokens: &mut TokenStream)3312         fn to_tokens(&self, tokens: &mut TokenStream) {
3313             outer_attrs_to_tokens(&self.attrs, tokens);
3314             self.member.to_tokens(tokens);
3315             if let Some(colon_token) = &self.colon_token {
3316                 colon_token.to_tokens(tokens);
3317                 self.expr.to_tokens(tokens);
3318             }
3319         }
3320     }
3321 
3322     #[cfg(feature = "full")]
3323     impl ToTokens for Arm {
to_tokens(&self, tokens: &mut TokenStream)3324         fn to_tokens(&self, tokens: &mut TokenStream) {
3325             tokens.append_all(&self.attrs);
3326             self.pat.to_tokens(tokens);
3327             if let Some((if_token, guard)) = &self.guard {
3328                 if_token.to_tokens(tokens);
3329                 guard.to_tokens(tokens);
3330             }
3331             self.fat_arrow_token.to_tokens(tokens);
3332             self.body.to_tokens(tokens);
3333             self.comma.to_tokens(tokens);
3334         }
3335     }
3336 }
3337