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