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