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