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 expr: ExprPath = input.parse()?;
1828         if expr.qself.is_some() {
1829             return Ok(Expr::Path(expr));
1830         }
1831 
1832         if input.peek(Token![!]) && !input.peek(Token![!=]) {
1833             let mut contains_arguments = false;
1834             for segment in &expr.path.segments {
1835                 match segment.arguments {
1836                     PathArguments::None => {}
1837                     PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
1838                         contains_arguments = true;
1839                     }
1840                 }
1841             }
1842 
1843             if !contains_arguments {
1844                 let bang_token: Token![!] = input.parse()?;
1845                 let (delimiter, tokens) = mac::parse_delimiter(input)?;
1846                 return Ok(Expr::Macro(ExprMacro {
1847                     attrs: Vec::new(),
1848                     mac: Macro {
1849                         path: expr.path,
1850                         bang_token,
1851                         delimiter,
1852                         tokens,
1853                     },
1854                 }));
1855             }
1856         }
1857 
1858         if allow_struct.0 && input.peek(token::Brace) {
1859             let outer_attrs = Vec::new();
1860             expr_struct_helper(input, outer_attrs, expr.path).map(Expr::Struct)
1861         } else {
1862             Ok(Expr::Path(expr))
1863         }
1864     }
1865 
1866     #[cfg(feature = "full")]
1867     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1868     impl Parse for ExprMacro {
parse(input: ParseStream) -> Result<Self>1869         fn parse(input: ParseStream) -> Result<Self> {
1870             Ok(ExprMacro {
1871                 attrs: Vec::new(),
1872                 mac: input.parse()?,
1873             })
1874         }
1875     }
1876 
1877     #[cfg(feature = "full")]
paren_or_tuple(input: ParseStream) -> Result<Expr>1878     fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
1879         let content;
1880         let paren_token = parenthesized!(content in input);
1881         let inner_attrs = content.call(Attribute::parse_inner)?;
1882         if content.is_empty() {
1883             return Ok(Expr::Tuple(ExprTuple {
1884                 attrs: inner_attrs,
1885                 paren_token,
1886                 elems: Punctuated::new(),
1887             }));
1888         }
1889 
1890         let first: Expr = content.parse()?;
1891         if content.is_empty() {
1892             return Ok(Expr::Paren(ExprParen {
1893                 attrs: inner_attrs,
1894                 paren_token,
1895                 expr: Box::new(first),
1896             }));
1897         }
1898 
1899         let mut elems = Punctuated::new();
1900         elems.push_value(first);
1901         while !content.is_empty() {
1902             let punct = content.parse()?;
1903             elems.push_punct(punct);
1904             if content.is_empty() {
1905                 break;
1906             }
1907             let value = content.parse()?;
1908             elems.push_value(value);
1909         }
1910         Ok(Expr::Tuple(ExprTuple {
1911             attrs: inner_attrs,
1912             paren_token,
1913             elems,
1914         }))
1915     }
1916 
1917     #[cfg(feature = "full")]
array_or_repeat(input: ParseStream) -> Result<Expr>1918     fn array_or_repeat(input: ParseStream) -> Result<Expr> {
1919         let content;
1920         let bracket_token = bracketed!(content in input);
1921         let inner_attrs = content.call(Attribute::parse_inner)?;
1922         if content.is_empty() {
1923             return Ok(Expr::Array(ExprArray {
1924                 attrs: inner_attrs,
1925                 bracket_token,
1926                 elems: Punctuated::new(),
1927             }));
1928         }
1929 
1930         let first: Expr = content.parse()?;
1931         if content.is_empty() || content.peek(Token![,]) {
1932             let mut elems = Punctuated::new();
1933             elems.push_value(first);
1934             while !content.is_empty() {
1935                 let punct = content.parse()?;
1936                 elems.push_punct(punct);
1937                 if content.is_empty() {
1938                     break;
1939                 }
1940                 let value = content.parse()?;
1941                 elems.push_value(value);
1942             }
1943             Ok(Expr::Array(ExprArray {
1944                 attrs: inner_attrs,
1945                 bracket_token,
1946                 elems,
1947             }))
1948         } else if content.peek(Token![;]) {
1949             let semi_token: Token![;] = content.parse()?;
1950             let len: Expr = content.parse()?;
1951             Ok(Expr::Repeat(ExprRepeat {
1952                 attrs: inner_attrs,
1953                 bracket_token,
1954                 expr: Box::new(first),
1955                 semi_token,
1956                 len: Box::new(len),
1957             }))
1958         } else {
1959             Err(content.error("expected `,` or `;`"))
1960         }
1961     }
1962 
1963     #[cfg(feature = "full")]
1964     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1965     impl Parse for ExprArray {
parse(input: ParseStream) -> Result<Self>1966         fn parse(input: ParseStream) -> Result<Self> {
1967             let content;
1968             let bracket_token = bracketed!(content in input);
1969             let inner_attrs = content.call(Attribute::parse_inner)?;
1970             let mut elems = Punctuated::new();
1971 
1972             while !content.is_empty() {
1973                 let first: Expr = content.parse()?;
1974                 elems.push_value(first);
1975                 if content.is_empty() {
1976                     break;
1977                 }
1978                 let punct = content.parse()?;
1979                 elems.push_punct(punct);
1980             }
1981 
1982             Ok(ExprArray {
1983                 attrs: inner_attrs,
1984                 bracket_token,
1985                 elems,
1986             })
1987         }
1988     }
1989 
1990     #[cfg(feature = "full")]
1991     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1992     impl Parse for ExprRepeat {
parse(input: ParseStream) -> Result<Self>1993         fn parse(input: ParseStream) -> Result<Self> {
1994             let content;
1995             Ok(ExprRepeat {
1996                 bracket_token: bracketed!(content in input),
1997                 attrs: content.call(Attribute::parse_inner)?,
1998                 expr: content.parse()?,
1999                 semi_token: content.parse()?,
2000                 len: content.parse()?,
2001             })
2002         }
2003     }
2004 
2005     #[cfg(feature = "full")]
expr_early(input: ParseStream) -> Result<Expr>2006     pub(crate) fn expr_early(input: ParseStream) -> Result<Expr> {
2007         let mut attrs = input.call(expr_attrs)?;
2008         let mut expr = if input.peek(Token![if]) {
2009             Expr::If(input.parse()?)
2010         } else if input.peek(Token![while]) {
2011             Expr::While(input.parse()?)
2012         } else if input.peek(Token![for]) {
2013             Expr::ForLoop(input.parse()?)
2014         } else if input.peek(Token![loop]) {
2015             Expr::Loop(input.parse()?)
2016         } else if input.peek(Token![match]) {
2017             Expr::Match(input.parse()?)
2018         } else if input.peek(Token![try]) && input.peek2(token::Brace) {
2019             Expr::TryBlock(input.parse()?)
2020         } else if input.peek(Token![unsafe]) {
2021             Expr::Unsafe(input.parse()?)
2022         } else if input.peek(Token![const]) {
2023             Expr::Verbatim(input.call(expr_const)?)
2024         } else if input.peek(token::Brace) {
2025             Expr::Block(input.parse()?)
2026         } else {
2027             let allow_struct = AllowStruct(true);
2028             let mut expr = unary_expr(input, allow_struct)?;
2029 
2030             attrs.extend(expr.replace_attrs(Vec::new()));
2031             expr.replace_attrs(attrs);
2032 
2033             return parse_expr(input, expr, allow_struct, Precedence::Any);
2034         };
2035 
2036         if input.peek(Token![.]) && !input.peek(Token![..]) || input.peek(Token![?]) {
2037             expr = trailer_helper(input, expr)?;
2038 
2039             attrs.extend(expr.replace_attrs(Vec::new()));
2040             expr.replace_attrs(attrs);
2041 
2042             let allow_struct = AllowStruct(true);
2043             return parse_expr(input, expr, allow_struct, Precedence::Any);
2044         }
2045 
2046         attrs.extend(expr.replace_attrs(Vec::new()));
2047         expr.replace_attrs(attrs);
2048         Ok(expr)
2049     }
2050 
2051     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2052     impl Parse for ExprLit {
parse(input: ParseStream) -> Result<Self>2053         fn parse(input: ParseStream) -> Result<Self> {
2054             Ok(ExprLit {
2055                 attrs: Vec::new(),
2056                 lit: input.parse()?,
2057             })
2058         }
2059     }
2060 
2061     #[cfg(feature = "full")]
expr_group(input: ParseStream) -> Result<ExprGroup>2062     fn expr_group(input: ParseStream) -> Result<ExprGroup> {
2063         let group = crate::group::parse_group(input)?;
2064         Ok(ExprGroup {
2065             attrs: Vec::new(),
2066             group_token: group.token,
2067             expr: group.content.parse()?,
2068         })
2069     }
2070 
2071     #[cfg(feature = "full")]
2072     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2073     impl Parse for ExprParen {
parse(input: ParseStream) -> Result<Self>2074         fn parse(input: ParseStream) -> Result<Self> {
2075             expr_paren(input)
2076         }
2077     }
2078 
expr_paren(input: ParseStream) -> Result<ExprParen>2079     fn expr_paren(input: ParseStream) -> Result<ExprParen> {
2080         let content;
2081         Ok(ExprParen {
2082             attrs: Vec::new(),
2083             paren_token: parenthesized!(content in input),
2084             expr: content.parse()?,
2085         })
2086     }
2087 
2088     #[cfg(feature = "full")]
generic_method_argument(input: ParseStream) -> Result<GenericMethodArgument>2089     fn generic_method_argument(input: ParseStream) -> Result<GenericMethodArgument> {
2090         if input.peek(Lit) {
2091             let lit = input.parse()?;
2092             return Ok(GenericMethodArgument::Const(Expr::Lit(lit)));
2093         }
2094 
2095         if input.peek(token::Brace) {
2096             let block: ExprBlock = input.parse()?;
2097             return Ok(GenericMethodArgument::Const(Expr::Block(block)));
2098         }
2099 
2100         input.parse().map(GenericMethodArgument::Type)
2101     }
2102 
2103     #[cfg(feature = "full")]
2104     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2105     impl Parse for ExprLet {
parse(input: ParseStream) -> Result<Self>2106         fn parse(input: ParseStream) -> Result<Self> {
2107             Ok(ExprLet {
2108                 attrs: Vec::new(),
2109                 let_token: input.parse()?,
2110                 pat: pat::parsing::multi_pat_with_leading_vert(input)?,
2111                 eq_token: input.parse()?,
2112                 expr: Box::new(input.call(Expr::parse_without_eager_brace)?),
2113             })
2114         }
2115     }
2116 
2117     #[cfg(feature = "full")]
2118     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2119     impl Parse for ExprIf {
parse(input: ParseStream) -> Result<Self>2120         fn parse(input: ParseStream) -> Result<Self> {
2121             let attrs = input.call(Attribute::parse_outer)?;
2122             Ok(ExprIf {
2123                 attrs,
2124                 if_token: input.parse()?,
2125                 cond: Box::new(input.call(Expr::parse_without_eager_brace)?),
2126                 then_branch: input.parse()?,
2127                 else_branch: {
2128                     if input.peek(Token![else]) {
2129                         Some(input.call(else_block)?)
2130                     } else {
2131                         None
2132                     }
2133                 },
2134             })
2135         }
2136     }
2137 
2138     #[cfg(feature = "full")]
else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)>2139     fn else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)> {
2140         let else_token: Token![else] = input.parse()?;
2141 
2142         let lookahead = input.lookahead1();
2143         let else_branch = if input.peek(Token![if]) {
2144             input.parse().map(Expr::If)?
2145         } else if input.peek(token::Brace) {
2146             Expr::Block(ExprBlock {
2147                 attrs: Vec::new(),
2148                 label: None,
2149                 block: input.parse()?,
2150             })
2151         } else {
2152             return Err(lookahead.error());
2153         };
2154 
2155         Ok((else_token, Box::new(else_branch)))
2156     }
2157 
2158     #[cfg(feature = "full")]
2159     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2160     impl Parse for ExprForLoop {
parse(input: ParseStream) -> Result<Self>2161         fn parse(input: ParseStream) -> Result<Self> {
2162             let mut attrs = input.call(Attribute::parse_outer)?;
2163             let label: Option<Label> = input.parse()?;
2164             let for_token: Token![for] = input.parse()?;
2165 
2166             let pat = pat::parsing::multi_pat_with_leading_vert(input)?;
2167 
2168             let in_token: Token![in] = input.parse()?;
2169             let expr: Expr = input.call(Expr::parse_without_eager_brace)?;
2170 
2171             let content;
2172             let brace_token = braced!(content in input);
2173             attr::parsing::parse_inner(&content, &mut attrs)?;
2174             let stmts = content.call(Block::parse_within)?;
2175 
2176             Ok(ExprForLoop {
2177                 attrs,
2178                 label,
2179                 for_token,
2180                 pat,
2181                 in_token,
2182                 expr: Box::new(expr),
2183                 body: Block { brace_token, stmts },
2184             })
2185         }
2186     }
2187 
2188     #[cfg(feature = "full")]
2189     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2190     impl Parse for ExprLoop {
parse(input: ParseStream) -> Result<Self>2191         fn parse(input: ParseStream) -> Result<Self> {
2192             let mut attrs = input.call(Attribute::parse_outer)?;
2193             let label: Option<Label> = input.parse()?;
2194             let loop_token: Token![loop] = input.parse()?;
2195 
2196             let content;
2197             let brace_token = braced!(content in input);
2198             attr::parsing::parse_inner(&content, &mut attrs)?;
2199             let stmts = content.call(Block::parse_within)?;
2200 
2201             Ok(ExprLoop {
2202                 attrs,
2203                 label,
2204                 loop_token,
2205                 body: Block { brace_token, stmts },
2206             })
2207         }
2208     }
2209 
2210     #[cfg(feature = "full")]
2211     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2212     impl Parse for ExprMatch {
parse(input: ParseStream) -> Result<Self>2213         fn parse(input: ParseStream) -> Result<Self> {
2214             let mut attrs = input.call(Attribute::parse_outer)?;
2215             let match_token: Token![match] = input.parse()?;
2216             let expr = Expr::parse_without_eager_brace(input)?;
2217 
2218             let content;
2219             let brace_token = braced!(content in input);
2220             attr::parsing::parse_inner(&content, &mut attrs)?;
2221 
2222             let mut arms = Vec::new();
2223             while !content.is_empty() {
2224                 arms.push(content.call(Arm::parse)?);
2225             }
2226 
2227             Ok(ExprMatch {
2228                 attrs,
2229                 match_token,
2230                 expr: Box::new(expr),
2231                 brace_token,
2232                 arms,
2233             })
2234         }
2235     }
2236 
2237     macro_rules! impl_by_parsing_expr {
2238         (
2239             $(
2240                 $expr_type:ty, $variant:ident, $msg:expr,
2241             )*
2242         ) => {
2243             $(
2244                 #[cfg(all(feature = "full", feature = "printing"))]
2245                 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2246                 impl Parse for $expr_type {
2247                     fn parse(input: ParseStream) -> Result<Self> {
2248                         let mut expr: Expr = input.parse()?;
2249                         loop {
2250                             match expr {
2251                                 Expr::$variant(inner) => return Ok(inner),
2252                                 Expr::Group(next) => expr = *next.expr,
2253                                 _ => return Err(Error::new_spanned(expr, $msg)),
2254                             }
2255                         }
2256                     }
2257                 }
2258             )*
2259         };
2260     }
2261 
2262     impl_by_parsing_expr! {
2263         ExprCall, Call, "expected function call expression",
2264         ExprMethodCall, MethodCall, "expected method call expression",
2265         ExprTuple, Tuple, "expected tuple expression",
2266         ExprBinary, Binary, "expected binary operation",
2267         ExprCast, Cast, "expected cast expression",
2268         ExprType, Type, "expected type ascription expression",
2269         ExprAssign, Assign, "expected assignment expression",
2270         ExprAssignOp, AssignOp, "expected compound assignment expression",
2271         ExprField, Field, "expected struct field access",
2272         ExprIndex, Index, "expected indexing expression",
2273         ExprRange, Range, "expected range expression",
2274         ExprTry, Try, "expected try expression",
2275     }
2276 
2277     #[cfg(feature = "full")]
2278     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2279     impl Parse for ExprBox {
parse(input: ParseStream) -> Result<Self>2280         fn parse(input: ParseStream) -> Result<Self> {
2281             let attrs = Vec::new();
2282             let allow_struct = AllowStruct(true);
2283             expr_box(input, attrs, allow_struct)
2284         }
2285     }
2286 
2287     #[cfg(feature = "full")]
expr_box( input: ParseStream, attrs: Vec<Attribute>, allow_struct: AllowStruct, ) -> Result<ExprBox>2288     fn expr_box(
2289         input: ParseStream,
2290         attrs: Vec<Attribute>,
2291         allow_struct: AllowStruct,
2292     ) -> Result<ExprBox> {
2293         Ok(ExprBox {
2294             attrs,
2295             box_token: input.parse()?,
2296             expr: Box::new(unary_expr(input, allow_struct)?),
2297         })
2298     }
2299 
2300     #[cfg(feature = "full")]
2301     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2302     impl Parse for ExprUnary {
parse(input: ParseStream) -> Result<Self>2303         fn parse(input: ParseStream) -> Result<Self> {
2304             let attrs = Vec::new();
2305             let allow_struct = AllowStruct(true);
2306             expr_unary(input, attrs, allow_struct)
2307         }
2308     }
2309 
2310     #[cfg(feature = "full")]
expr_unary( input: ParseStream, attrs: Vec<Attribute>, allow_struct: AllowStruct, ) -> Result<ExprUnary>2311     fn expr_unary(
2312         input: ParseStream,
2313         attrs: Vec<Attribute>,
2314         allow_struct: AllowStruct,
2315     ) -> Result<ExprUnary> {
2316         Ok(ExprUnary {
2317             attrs,
2318             op: input.parse()?,
2319             expr: Box::new(unary_expr(input, allow_struct)?),
2320         })
2321     }
2322 
2323     #[cfg(feature = "full")]
2324     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2325     impl Parse for ExprClosure {
parse(input: ParseStream) -> Result<Self>2326         fn parse(input: ParseStream) -> Result<Self> {
2327             let allow_struct = AllowStruct(true);
2328             expr_closure(input, allow_struct)
2329         }
2330     }
2331 
2332     #[cfg(feature = "full")]
2333     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2334     impl Parse for ExprReference {
parse(input: ParseStream) -> Result<Self>2335         fn parse(input: ParseStream) -> Result<Self> {
2336             let allow_struct = AllowStruct(true);
2337             Ok(ExprReference {
2338                 attrs: Vec::new(),
2339                 and_token: input.parse()?,
2340                 raw: Reserved::default(),
2341                 mutability: input.parse()?,
2342                 expr: Box::new(unary_expr(input, allow_struct)?),
2343             })
2344         }
2345     }
2346 
2347     #[cfg(feature = "full")]
2348     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2349     impl Parse for ExprBreak {
parse(input: ParseStream) -> Result<Self>2350         fn parse(input: ParseStream) -> Result<Self> {
2351             let allow_struct = AllowStruct(true);
2352             expr_break(input, allow_struct)
2353         }
2354     }
2355 
2356     #[cfg(feature = "full")]
2357     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2358     impl Parse for ExprReturn {
parse(input: ParseStream) -> Result<Self>2359         fn parse(input: ParseStream) -> Result<Self> {
2360             let allow_struct = AllowStruct(true);
2361             expr_ret(input, allow_struct)
2362         }
2363     }
2364 
2365     #[cfg(feature = "full")]
2366     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2367     impl Parse for ExprTryBlock {
parse(input: ParseStream) -> Result<Self>2368         fn parse(input: ParseStream) -> Result<Self> {
2369             Ok(ExprTryBlock {
2370                 attrs: Vec::new(),
2371                 try_token: input.parse()?,
2372                 block: input.parse()?,
2373             })
2374         }
2375     }
2376 
2377     #[cfg(feature = "full")]
2378     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2379     impl Parse for ExprYield {
parse(input: ParseStream) -> Result<Self>2380         fn parse(input: ParseStream) -> Result<Self> {
2381             Ok(ExprYield {
2382                 attrs: Vec::new(),
2383                 yield_token: input.parse()?,
2384                 expr: {
2385                     if !input.is_empty() && !input.peek(Token![,]) && !input.peek(Token![;]) {
2386                         Some(input.parse()?)
2387                     } else {
2388                         None
2389                     }
2390                 },
2391             })
2392         }
2393     }
2394 
2395     #[cfg(feature = "full")]
expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure>2396     fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
2397         let asyncness: Option<Token![async]> = input.parse()?;
2398         let movability: Option<Token![static]> = if asyncness.is_none() {
2399             input.parse()?
2400         } else {
2401             None
2402         };
2403         let capture: Option<Token![move]> = input.parse()?;
2404         let or1_token: Token![|] = input.parse()?;
2405 
2406         let mut inputs = Punctuated::new();
2407         loop {
2408             if input.peek(Token![|]) {
2409                 break;
2410             }
2411             let value = closure_arg(input)?;
2412             inputs.push_value(value);
2413             if input.peek(Token![|]) {
2414                 break;
2415             }
2416             let punct: Token![,] = input.parse()?;
2417             inputs.push_punct(punct);
2418         }
2419 
2420         let or2_token: Token![|] = input.parse()?;
2421 
2422         let (output, body) = if input.peek(Token![->]) {
2423             let arrow_token: Token![->] = input.parse()?;
2424             let ty: Type = input.parse()?;
2425             let body: Block = input.parse()?;
2426             let output = ReturnType::Type(arrow_token, Box::new(ty));
2427             let block = Expr::Block(ExprBlock {
2428                 attrs: Vec::new(),
2429                 label: None,
2430                 block: body,
2431             });
2432             (output, block)
2433         } else {
2434             let body = ambiguous_expr(input, allow_struct)?;
2435             (ReturnType::Default, body)
2436         };
2437 
2438         Ok(ExprClosure {
2439             attrs: Vec::new(),
2440             asyncness,
2441             movability,
2442             capture,
2443             or1_token,
2444             inputs,
2445             or2_token,
2446             output,
2447             body: Box::new(body),
2448         })
2449     }
2450 
2451     #[cfg(feature = "full")]
2452     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2453     impl Parse for ExprAsync {
parse(input: ParseStream) -> Result<Self>2454         fn parse(input: ParseStream) -> Result<Self> {
2455             Ok(ExprAsync {
2456                 attrs: Vec::new(),
2457                 async_token: input.parse()?,
2458                 capture: input.parse()?,
2459                 block: input.parse()?,
2460             })
2461         }
2462     }
2463 
2464     #[cfg(feature = "full")]
closure_arg(input: ParseStream) -> Result<Pat>2465     fn closure_arg(input: ParseStream) -> Result<Pat> {
2466         let attrs = input.call(Attribute::parse_outer)?;
2467         let mut pat: Pat = input.parse()?;
2468 
2469         if input.peek(Token![:]) {
2470             Ok(Pat::Type(PatType {
2471                 attrs,
2472                 pat: Box::new(pat),
2473                 colon_token: input.parse()?,
2474                 ty: input.parse()?,
2475             }))
2476         } else {
2477             match &mut pat {
2478                 Pat::Box(pat) => pat.attrs = attrs,
2479                 Pat::Ident(pat) => pat.attrs = attrs,
2480                 Pat::Lit(pat) => pat.attrs = attrs,
2481                 Pat::Macro(pat) => pat.attrs = attrs,
2482                 Pat::Or(pat) => pat.attrs = attrs,
2483                 Pat::Path(pat) => pat.attrs = attrs,
2484                 Pat::Range(pat) => pat.attrs = attrs,
2485                 Pat::Reference(pat) => pat.attrs = attrs,
2486                 Pat::Rest(pat) => pat.attrs = attrs,
2487                 Pat::Slice(pat) => pat.attrs = attrs,
2488                 Pat::Struct(pat) => pat.attrs = attrs,
2489                 Pat::Tuple(pat) => pat.attrs = attrs,
2490                 Pat::TupleStruct(pat) => pat.attrs = attrs,
2491                 Pat::Type(_) => unreachable!(),
2492                 Pat::Verbatim(_) => {}
2493                 Pat::Wild(pat) => pat.attrs = attrs,
2494 
2495                 #[cfg(test)]
2496                 Pat::__TestExhaustive(_) => unimplemented!(),
2497                 #[cfg(not(test))]
2498                 _ => unreachable!(),
2499             }
2500             Ok(pat)
2501         }
2502     }
2503 
2504     #[cfg(feature = "full")]
2505     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2506     impl Parse for ExprWhile {
parse(input: ParseStream) -> Result<Self>2507         fn parse(input: ParseStream) -> Result<Self> {
2508             let mut attrs = input.call(Attribute::parse_outer)?;
2509             let label: Option<Label> = input.parse()?;
2510             let while_token: Token![while] = input.parse()?;
2511             let cond = Expr::parse_without_eager_brace(input)?;
2512 
2513             let content;
2514             let brace_token = braced!(content in input);
2515             attr::parsing::parse_inner(&content, &mut attrs)?;
2516             let stmts = content.call(Block::parse_within)?;
2517 
2518             Ok(ExprWhile {
2519                 attrs,
2520                 label,
2521                 while_token,
2522                 cond: Box::new(cond),
2523                 body: Block { brace_token, stmts },
2524             })
2525         }
2526     }
2527 
2528     #[cfg(feature = "full")]
2529     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2530     impl Parse for Label {
parse(input: ParseStream) -> Result<Self>2531         fn parse(input: ParseStream) -> Result<Self> {
2532             Ok(Label {
2533                 name: input.parse()?,
2534                 colon_token: input.parse()?,
2535             })
2536         }
2537     }
2538 
2539     #[cfg(feature = "full")]
2540     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2541     impl Parse for Option<Label> {
parse(input: ParseStream) -> Result<Self>2542         fn parse(input: ParseStream) -> Result<Self> {
2543             if input.peek(Lifetime) {
2544                 input.parse().map(Some)
2545             } else {
2546                 Ok(None)
2547             }
2548         }
2549     }
2550 
2551     #[cfg(feature = "full")]
2552     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2553     impl Parse for ExprContinue {
parse(input: ParseStream) -> Result<Self>2554         fn parse(input: ParseStream) -> Result<Self> {
2555             Ok(ExprContinue {
2556                 attrs: Vec::new(),
2557                 continue_token: input.parse()?,
2558                 label: input.parse()?,
2559             })
2560         }
2561     }
2562 
2563     #[cfg(feature = "full")]
expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak>2564     fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
2565         Ok(ExprBreak {
2566             attrs: Vec::new(),
2567             break_token: input.parse()?,
2568             label: input.parse()?,
2569             expr: {
2570                 if input.is_empty()
2571                     || input.peek(Token![,])
2572                     || input.peek(Token![;])
2573                     || !allow_struct.0 && input.peek(token::Brace)
2574                 {
2575                     None
2576                 } else {
2577                     let expr = ambiguous_expr(input, allow_struct)?;
2578                     Some(Box::new(expr))
2579                 }
2580             },
2581         })
2582     }
2583 
2584     #[cfg(feature = "full")]
expr_ret(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn>2585     fn expr_ret(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn> {
2586         Ok(ExprReturn {
2587             attrs: Vec::new(),
2588             return_token: input.parse()?,
2589             expr: {
2590                 if input.is_empty() || input.peek(Token![,]) || input.peek(Token![;]) {
2591                     None
2592                 } else {
2593                     // NOTE: return is greedy and eats blocks after it even when in a
2594                     // position where structs are not allowed, such as in if statement
2595                     // conditions. For example:
2596                     //
2597                     // if return { println!("A") } {} // Prints "A"
2598                     let expr = ambiguous_expr(input, allow_struct)?;
2599                     Some(Box::new(expr))
2600                 }
2601             },
2602         })
2603     }
2604 
2605     #[cfg(feature = "full")]
2606     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2607     impl Parse for FieldValue {
parse(input: ParseStream) -> Result<Self>2608         fn parse(input: ParseStream) -> Result<Self> {
2609             let attrs = input.call(Attribute::parse_outer)?;
2610             let member: Member = input.parse()?;
2611             let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() {
2612                 let colon_token: Token![:] = input.parse()?;
2613                 let value: Expr = input.parse()?;
2614                 (Some(colon_token), value)
2615             } else if let Member::Named(ident) = &member {
2616                 let value = Expr::Path(ExprPath {
2617                     attrs: Vec::new(),
2618                     qself: None,
2619                     path: Path::from(ident.clone()),
2620                 });
2621                 (None, value)
2622             } else {
2623                 unreachable!()
2624             };
2625 
2626             Ok(FieldValue {
2627                 attrs,
2628                 member,
2629                 colon_token,
2630                 expr: value,
2631             })
2632         }
2633     }
2634 
2635     #[cfg(feature = "full")]
2636     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2637     impl Parse for ExprStruct {
parse(input: ParseStream) -> Result<Self>2638         fn parse(input: ParseStream) -> Result<Self> {
2639             let attrs = Vec::new();
2640             let path: Path = input.parse()?;
2641             expr_struct_helper(input, attrs, path)
2642         }
2643     }
2644 
2645     #[cfg(feature = "full")]
expr_struct_helper( input: ParseStream, mut attrs: Vec<Attribute>, path: Path, ) -> Result<ExprStruct>2646     fn expr_struct_helper(
2647         input: ParseStream,
2648         mut attrs: Vec<Attribute>,
2649         path: Path,
2650     ) -> Result<ExprStruct> {
2651         let content;
2652         let brace_token = braced!(content in input);
2653         attr::parsing::parse_inner(&content, &mut attrs)?;
2654 
2655         let mut fields = Punctuated::new();
2656         while !content.is_empty() {
2657             if content.peek(Token![..]) {
2658                 return Ok(ExprStruct {
2659                     attrs,
2660                     brace_token,
2661                     path,
2662                     fields,
2663                     dot2_token: Some(content.parse()?),
2664                     rest: if content.is_empty() {
2665                         None
2666                     } else {
2667                         Some(Box::new(content.parse()?))
2668                     },
2669                 });
2670             }
2671 
2672             fields.push(content.parse()?);
2673             if content.is_empty() {
2674                 break;
2675             }
2676             let punct: Token![,] = content.parse()?;
2677             fields.push_punct(punct);
2678         }
2679 
2680         Ok(ExprStruct {
2681             attrs,
2682             brace_token,
2683             path,
2684             fields,
2685             dot2_token: None,
2686             rest: None,
2687         })
2688     }
2689 
2690     #[cfg(feature = "full")]
2691     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2692     impl Parse for ExprUnsafe {
parse(input: ParseStream) -> Result<Self>2693         fn parse(input: ParseStream) -> Result<Self> {
2694             let unsafe_token: Token![unsafe] = input.parse()?;
2695 
2696             let content;
2697             let brace_token = braced!(content in input);
2698             let inner_attrs = content.call(Attribute::parse_inner)?;
2699             let stmts = content.call(Block::parse_within)?;
2700 
2701             Ok(ExprUnsafe {
2702                 attrs: inner_attrs,
2703                 unsafe_token,
2704                 block: Block { brace_token, stmts },
2705             })
2706         }
2707     }
2708 
2709     #[cfg(feature = "full")]
expr_const(input: ParseStream) -> Result<TokenStream>2710     pub(crate) fn expr_const(input: ParseStream) -> Result<TokenStream> {
2711         let begin = input.fork();
2712         input.parse::<Token![const]>()?;
2713 
2714         let content;
2715         braced!(content in input);
2716         content.call(Attribute::parse_inner)?;
2717         content.call(Block::parse_within)?;
2718 
2719         Ok(verbatim::between(begin, input))
2720     }
2721 
2722     #[cfg(feature = "full")]
2723     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2724     impl Parse for ExprBlock {
parse(input: ParseStream) -> Result<Self>2725         fn parse(input: ParseStream) -> Result<Self> {
2726             let mut attrs = input.call(Attribute::parse_outer)?;
2727             let label: Option<Label> = input.parse()?;
2728 
2729             let content;
2730             let brace_token = braced!(content in input);
2731             attr::parsing::parse_inner(&content, &mut attrs)?;
2732             let stmts = content.call(Block::parse_within)?;
2733 
2734             Ok(ExprBlock {
2735                 attrs,
2736                 label,
2737                 block: Block { brace_token, stmts },
2738             })
2739         }
2740     }
2741 
2742     #[cfg(feature = "full")]
expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange>2743     fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
2744         Ok(ExprRange {
2745             attrs: Vec::new(),
2746             from: None,
2747             limits: input.parse()?,
2748             to: {
2749                 if input.is_empty()
2750                     || input.peek(Token![,])
2751                     || input.peek(Token![;])
2752                     || input.peek(Token![.]) && !input.peek(Token![..])
2753                     || !allow_struct.0 && input.peek(token::Brace)
2754                 {
2755                     None
2756                 } else {
2757                     let to = ambiguous_expr(input, allow_struct)?;
2758                     Some(Box::new(to))
2759                 }
2760             },
2761         })
2762     }
2763 
2764     #[cfg(feature = "full")]
2765     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2766     impl Parse for RangeLimits {
parse(input: ParseStream) -> Result<Self>2767         fn parse(input: ParseStream) -> Result<Self> {
2768             let lookahead = input.lookahead1();
2769             if lookahead.peek(Token![..=]) {
2770                 input.parse().map(RangeLimits::Closed)
2771             } else if lookahead.peek(Token![...]) {
2772                 let dot3: Token![...] = input.parse()?;
2773                 Ok(RangeLimits::Closed(Token![..=](dot3.spans)))
2774             } else if lookahead.peek(Token![..]) {
2775                 input.parse().map(RangeLimits::HalfOpen)
2776             } else {
2777                 Err(lookahead.error())
2778             }
2779         }
2780     }
2781 
2782     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2783     impl Parse for ExprPath {
parse(input: ParseStream) -> Result<Self>2784         fn parse(input: ParseStream) -> Result<Self> {
2785             #[cfg(not(feature = "full"))]
2786             let attrs = Vec::new();
2787             #[cfg(feature = "full")]
2788             let attrs = input.call(Attribute::parse_outer)?;
2789 
2790             let (qself, path) = path::parsing::qpath(input, true)?;
2791 
2792             Ok(ExprPath { attrs, qself, path })
2793         }
2794     }
2795 
2796     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2797     impl Parse for Member {
parse(input: ParseStream) -> Result<Self>2798         fn parse(input: ParseStream) -> Result<Self> {
2799             if input.peek(Ident) {
2800                 input.parse().map(Member::Named)
2801             } else if input.peek(LitInt) {
2802                 input.parse().map(Member::Unnamed)
2803             } else {
2804                 Err(input.error("expected identifier or integer"))
2805             }
2806         }
2807     }
2808 
2809     #[cfg(feature = "full")]
2810     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2811     impl Parse for Arm {
parse(input: ParseStream) -> Result<Arm>2812         fn parse(input: ParseStream) -> Result<Arm> {
2813             let requires_comma;
2814             Ok(Arm {
2815                 attrs: input.call(Attribute::parse_outer)?,
2816                 pat: pat::parsing::multi_pat_with_leading_vert(input)?,
2817                 guard: {
2818                     if input.peek(Token![if]) {
2819                         let if_token: Token![if] = input.parse()?;
2820                         let guard: Expr = input.parse()?;
2821                         Some((if_token, Box::new(guard)))
2822                     } else {
2823                         None
2824                     }
2825                 },
2826                 fat_arrow_token: input.parse()?,
2827                 body: {
2828                     let body = input.call(expr_early)?;
2829                     requires_comma = requires_terminator(&body);
2830                     Box::new(body)
2831                 },
2832                 comma: {
2833                     if requires_comma && !input.is_empty() {
2834                         Some(input.parse()?)
2835                     } else {
2836                         input.parse()?
2837                     }
2838                 },
2839             })
2840         }
2841     }
2842 
2843     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2844     impl Parse for Index {
parse(input: ParseStream) -> Result<Self>2845         fn parse(input: ParseStream) -> Result<Self> {
2846             let lit: LitInt = input.parse()?;
2847             if lit.suffix().is_empty() {
2848                 Ok(Index {
2849                     index: lit
2850                         .base10_digits()
2851                         .parse()
2852                         .map_err(|err| Error::new(lit.span(), err))?,
2853                     span: lit.span(),
2854                 })
2855             } else {
2856                 Err(Error::new(lit.span(), "expected unsuffixed integer"))
2857             }
2858         }
2859     }
2860 
multi_index(e: &mut Expr, dot_token: &mut Token![.], float: LitFloat) -> Result<bool>2861     fn multi_index(e: &mut Expr, dot_token: &mut Token![.], float: LitFloat) -> Result<bool> {
2862         let mut float_repr = float.to_string();
2863         let trailing_dot = float_repr.ends_with('.');
2864         if trailing_dot {
2865             float_repr.truncate(float_repr.len() - 1);
2866         }
2867         for part in float_repr.split('.') {
2868             let index = crate::parse_str(part).map_err(|err| Error::new(float.span(), err))?;
2869             let base = mem::replace(e, Expr::__TestExhaustive(crate::private(())));
2870             *e = Expr::Field(ExprField {
2871                 attrs: Vec::new(),
2872                 base: Box::new(base),
2873                 dot_token: Token![.](dot_token.span),
2874                 member: Member::Unnamed(index),
2875             });
2876             *dot_token = Token![.](float.span());
2877         }
2878         Ok(!trailing_dot)
2879     }
2880 
2881     #[cfg(feature = "full")]
2882     impl Member {
is_named(&self) -> bool2883         fn is_named(&self) -> bool {
2884             match *self {
2885                 Member::Named(_) => true,
2886                 Member::Unnamed(_) => false,
2887             }
2888         }
2889     }
2890 }
2891 
2892 #[cfg(feature = "printing")]
2893 pub(crate) mod printing {
2894     use super::*;
2895     #[cfg(feature = "full")]
2896     use crate::attr::FilterAttrs;
2897     use proc_macro2::{Literal, TokenStream};
2898     use quote::{ToTokens, TokenStreamExt};
2899 
2900     // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2901     // before appending it to `TokenStream`.
2902     #[cfg(feature = "full")]
wrap_bare_struct(tokens: &mut TokenStream, e: &Expr)2903     fn wrap_bare_struct(tokens: &mut TokenStream, e: &Expr) {
2904         if let Expr::Struct(_) = *e {
2905             token::Paren::default().surround(tokens, |tokens| {
2906                 e.to_tokens(tokens);
2907             });
2908         } else {
2909             e.to_tokens(tokens);
2910         }
2911     }
2912 
2913     #[cfg(feature = "full")]
outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream)2914     pub(crate) fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
2915         tokens.append_all(attrs.outer());
2916     }
2917 
2918     #[cfg(feature = "full")]
inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream)2919     fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
2920         tokens.append_all(attrs.inner());
2921     }
2922 
2923     #[cfg(not(feature = "full"))]
outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream)2924     pub(crate) fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
2925 
2926     #[cfg(not(feature = "full"))]
inner_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream)2927     fn inner_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
2928 
2929     #[cfg(feature = "full")]
2930     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
2931     impl ToTokens for ExprBox {
to_tokens(&self, tokens: &mut TokenStream)2932         fn to_tokens(&self, tokens: &mut TokenStream) {
2933             outer_attrs_to_tokens(&self.attrs, tokens);
2934             self.box_token.to_tokens(tokens);
2935             self.expr.to_tokens(tokens);
2936         }
2937     }
2938 
2939     #[cfg(feature = "full")]
2940     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
2941     impl ToTokens for ExprArray {
to_tokens(&self, tokens: &mut TokenStream)2942         fn to_tokens(&self, tokens: &mut TokenStream) {
2943             outer_attrs_to_tokens(&self.attrs, tokens);
2944             self.bracket_token.surround(tokens, |tokens| {
2945                 inner_attrs_to_tokens(&self.attrs, tokens);
2946                 self.elems.to_tokens(tokens);
2947             });
2948         }
2949     }
2950 
2951     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
2952     impl ToTokens for ExprCall {
to_tokens(&self, tokens: &mut TokenStream)2953         fn to_tokens(&self, tokens: &mut TokenStream) {
2954             outer_attrs_to_tokens(&self.attrs, tokens);
2955             self.func.to_tokens(tokens);
2956             self.paren_token.surround(tokens, |tokens| {
2957                 self.args.to_tokens(tokens);
2958             });
2959         }
2960     }
2961 
2962     #[cfg(feature = "full")]
2963     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
2964     impl ToTokens for ExprMethodCall {
to_tokens(&self, tokens: &mut TokenStream)2965         fn to_tokens(&self, tokens: &mut TokenStream) {
2966             outer_attrs_to_tokens(&self.attrs, tokens);
2967             self.receiver.to_tokens(tokens);
2968             self.dot_token.to_tokens(tokens);
2969             self.method.to_tokens(tokens);
2970             self.turbofish.to_tokens(tokens);
2971             self.paren_token.surround(tokens, |tokens| {
2972                 self.args.to_tokens(tokens);
2973             });
2974         }
2975     }
2976 
2977     #[cfg(feature = "full")]
2978     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
2979     impl ToTokens for MethodTurbofish {
to_tokens(&self, tokens: &mut TokenStream)2980         fn to_tokens(&self, tokens: &mut TokenStream) {
2981             self.colon2_token.to_tokens(tokens);
2982             self.lt_token.to_tokens(tokens);
2983             self.args.to_tokens(tokens);
2984             self.gt_token.to_tokens(tokens);
2985         }
2986     }
2987 
2988     #[cfg(feature = "full")]
2989     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
2990     impl ToTokens for GenericMethodArgument {
to_tokens(&self, tokens: &mut TokenStream)2991         fn to_tokens(&self, tokens: &mut TokenStream) {
2992             match self {
2993                 GenericMethodArgument::Type(t) => t.to_tokens(tokens),
2994                 GenericMethodArgument::Const(c) => c.to_tokens(tokens),
2995             }
2996         }
2997     }
2998 
2999     #[cfg(feature = "full")]
3000     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3001     impl ToTokens for ExprTuple {
to_tokens(&self, tokens: &mut TokenStream)3002         fn to_tokens(&self, tokens: &mut TokenStream) {
3003             outer_attrs_to_tokens(&self.attrs, tokens);
3004             self.paren_token.surround(tokens, |tokens| {
3005                 inner_attrs_to_tokens(&self.attrs, tokens);
3006                 self.elems.to_tokens(tokens);
3007                 // If we only have one argument, we need a trailing comma to
3008                 // distinguish ExprTuple from ExprParen.
3009                 if self.elems.len() == 1 && !self.elems.trailing_punct() {
3010                     <Token![,]>::default().to_tokens(tokens);
3011                 }
3012             });
3013         }
3014     }
3015 
3016     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3017     impl ToTokens for ExprBinary {
to_tokens(&self, tokens: &mut TokenStream)3018         fn to_tokens(&self, tokens: &mut TokenStream) {
3019             outer_attrs_to_tokens(&self.attrs, tokens);
3020             self.left.to_tokens(tokens);
3021             self.op.to_tokens(tokens);
3022             self.right.to_tokens(tokens);
3023         }
3024     }
3025 
3026     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3027     impl ToTokens for ExprUnary {
to_tokens(&self, tokens: &mut TokenStream)3028         fn to_tokens(&self, tokens: &mut TokenStream) {
3029             outer_attrs_to_tokens(&self.attrs, tokens);
3030             self.op.to_tokens(tokens);
3031             self.expr.to_tokens(tokens);
3032         }
3033     }
3034 
3035     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3036     impl ToTokens for ExprLit {
to_tokens(&self, tokens: &mut TokenStream)3037         fn to_tokens(&self, tokens: &mut TokenStream) {
3038             outer_attrs_to_tokens(&self.attrs, tokens);
3039             self.lit.to_tokens(tokens);
3040         }
3041     }
3042 
3043     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3044     impl ToTokens for ExprCast {
to_tokens(&self, tokens: &mut TokenStream)3045         fn to_tokens(&self, tokens: &mut TokenStream) {
3046             outer_attrs_to_tokens(&self.attrs, tokens);
3047             self.expr.to_tokens(tokens);
3048             self.as_token.to_tokens(tokens);
3049             self.ty.to_tokens(tokens);
3050         }
3051     }
3052 
3053     #[cfg(feature = "full")]
3054     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3055     impl ToTokens for ExprType {
to_tokens(&self, tokens: &mut TokenStream)3056         fn to_tokens(&self, tokens: &mut TokenStream) {
3057             outer_attrs_to_tokens(&self.attrs, tokens);
3058             self.expr.to_tokens(tokens);
3059             self.colon_token.to_tokens(tokens);
3060             self.ty.to_tokens(tokens);
3061         }
3062     }
3063 
3064     #[cfg(feature = "full")]
maybe_wrap_else(tokens: &mut TokenStream, else_: &Option<(Token![else], Box<Expr>)>)3065     fn maybe_wrap_else(tokens: &mut TokenStream, else_: &Option<(Token![else], Box<Expr>)>) {
3066         if let Some((else_token, else_)) = else_ {
3067             else_token.to_tokens(tokens);
3068 
3069             // If we are not one of the valid expressions to exist in an else
3070             // clause, wrap ourselves in a block.
3071             match **else_ {
3072                 Expr::If(_) | Expr::Block(_) => {
3073                     else_.to_tokens(tokens);
3074                 }
3075                 _ => {
3076                     token::Brace::default().surround(tokens, |tokens| {
3077                         else_.to_tokens(tokens);
3078                     });
3079                 }
3080             }
3081         }
3082     }
3083 
3084     #[cfg(feature = "full")]
3085     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3086     impl ToTokens for ExprLet {
to_tokens(&self, tokens: &mut TokenStream)3087         fn to_tokens(&self, tokens: &mut TokenStream) {
3088             outer_attrs_to_tokens(&self.attrs, tokens);
3089             self.let_token.to_tokens(tokens);
3090             self.pat.to_tokens(tokens);
3091             self.eq_token.to_tokens(tokens);
3092             wrap_bare_struct(tokens, &self.expr);
3093         }
3094     }
3095 
3096     #[cfg(feature = "full")]
3097     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3098     impl ToTokens for ExprIf {
to_tokens(&self, tokens: &mut TokenStream)3099         fn to_tokens(&self, tokens: &mut TokenStream) {
3100             outer_attrs_to_tokens(&self.attrs, tokens);
3101             self.if_token.to_tokens(tokens);
3102             wrap_bare_struct(tokens, &self.cond);
3103             self.then_branch.to_tokens(tokens);
3104             maybe_wrap_else(tokens, &self.else_branch);
3105         }
3106     }
3107 
3108     #[cfg(feature = "full")]
3109     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3110     impl ToTokens for ExprWhile {
to_tokens(&self, tokens: &mut TokenStream)3111         fn to_tokens(&self, tokens: &mut TokenStream) {
3112             outer_attrs_to_tokens(&self.attrs, tokens);
3113             self.label.to_tokens(tokens);
3114             self.while_token.to_tokens(tokens);
3115             wrap_bare_struct(tokens, &self.cond);
3116             self.body.brace_token.surround(tokens, |tokens| {
3117                 inner_attrs_to_tokens(&self.attrs, tokens);
3118                 tokens.append_all(&self.body.stmts);
3119             });
3120         }
3121     }
3122 
3123     #[cfg(feature = "full")]
3124     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3125     impl ToTokens for ExprForLoop {
to_tokens(&self, tokens: &mut TokenStream)3126         fn to_tokens(&self, tokens: &mut TokenStream) {
3127             outer_attrs_to_tokens(&self.attrs, tokens);
3128             self.label.to_tokens(tokens);
3129             self.for_token.to_tokens(tokens);
3130             self.pat.to_tokens(tokens);
3131             self.in_token.to_tokens(tokens);
3132             wrap_bare_struct(tokens, &self.expr);
3133             self.body.brace_token.surround(tokens, |tokens| {
3134                 inner_attrs_to_tokens(&self.attrs, tokens);
3135                 tokens.append_all(&self.body.stmts);
3136             });
3137         }
3138     }
3139 
3140     #[cfg(feature = "full")]
3141     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3142     impl ToTokens for ExprLoop {
to_tokens(&self, tokens: &mut TokenStream)3143         fn to_tokens(&self, tokens: &mut TokenStream) {
3144             outer_attrs_to_tokens(&self.attrs, tokens);
3145             self.label.to_tokens(tokens);
3146             self.loop_token.to_tokens(tokens);
3147             self.body.brace_token.surround(tokens, |tokens| {
3148                 inner_attrs_to_tokens(&self.attrs, tokens);
3149                 tokens.append_all(&self.body.stmts);
3150             });
3151         }
3152     }
3153 
3154     #[cfg(feature = "full")]
3155     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3156     impl ToTokens for ExprMatch {
to_tokens(&self, tokens: &mut TokenStream)3157         fn to_tokens(&self, tokens: &mut TokenStream) {
3158             outer_attrs_to_tokens(&self.attrs, tokens);
3159             self.match_token.to_tokens(tokens);
3160             wrap_bare_struct(tokens, &self.expr);
3161             self.brace_token.surround(tokens, |tokens| {
3162                 inner_attrs_to_tokens(&self.attrs, tokens);
3163                 for (i, arm) in self.arms.iter().enumerate() {
3164                     arm.to_tokens(tokens);
3165                     // Ensure that we have a comma after a non-block arm, except
3166                     // for the last one.
3167                     let is_last = i == self.arms.len() - 1;
3168                     if !is_last && requires_terminator(&arm.body) && arm.comma.is_none() {
3169                         <Token![,]>::default().to_tokens(tokens);
3170                     }
3171                 }
3172             });
3173         }
3174     }
3175 
3176     #[cfg(feature = "full")]
3177     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3178     impl ToTokens for ExprAsync {
to_tokens(&self, tokens: &mut TokenStream)3179         fn to_tokens(&self, tokens: &mut TokenStream) {
3180             outer_attrs_to_tokens(&self.attrs, tokens);
3181             self.async_token.to_tokens(tokens);
3182             self.capture.to_tokens(tokens);
3183             self.block.to_tokens(tokens);
3184         }
3185     }
3186 
3187     #[cfg(feature = "full")]
3188     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3189     impl ToTokens for ExprAwait {
to_tokens(&self, tokens: &mut TokenStream)3190         fn to_tokens(&self, tokens: &mut TokenStream) {
3191             outer_attrs_to_tokens(&self.attrs, tokens);
3192             self.base.to_tokens(tokens);
3193             self.dot_token.to_tokens(tokens);
3194             self.await_token.to_tokens(tokens);
3195         }
3196     }
3197 
3198     #[cfg(feature = "full")]
3199     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3200     impl ToTokens for ExprTryBlock {
to_tokens(&self, tokens: &mut TokenStream)3201         fn to_tokens(&self, tokens: &mut TokenStream) {
3202             outer_attrs_to_tokens(&self.attrs, tokens);
3203             self.try_token.to_tokens(tokens);
3204             self.block.to_tokens(tokens);
3205         }
3206     }
3207 
3208     #[cfg(feature = "full")]
3209     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3210     impl ToTokens for ExprYield {
to_tokens(&self, tokens: &mut TokenStream)3211         fn to_tokens(&self, tokens: &mut TokenStream) {
3212             outer_attrs_to_tokens(&self.attrs, tokens);
3213             self.yield_token.to_tokens(tokens);
3214             self.expr.to_tokens(tokens);
3215         }
3216     }
3217 
3218     #[cfg(feature = "full")]
3219     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3220     impl ToTokens for ExprClosure {
to_tokens(&self, tokens: &mut TokenStream)3221         fn to_tokens(&self, tokens: &mut TokenStream) {
3222             outer_attrs_to_tokens(&self.attrs, tokens);
3223             self.asyncness.to_tokens(tokens);
3224             self.movability.to_tokens(tokens);
3225             self.capture.to_tokens(tokens);
3226             self.or1_token.to_tokens(tokens);
3227             self.inputs.to_tokens(tokens);
3228             self.or2_token.to_tokens(tokens);
3229             self.output.to_tokens(tokens);
3230             self.body.to_tokens(tokens);
3231         }
3232     }
3233 
3234     #[cfg(feature = "full")]
3235     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3236     impl ToTokens for ExprUnsafe {
to_tokens(&self, tokens: &mut TokenStream)3237         fn to_tokens(&self, tokens: &mut TokenStream) {
3238             outer_attrs_to_tokens(&self.attrs, tokens);
3239             self.unsafe_token.to_tokens(tokens);
3240             self.block.brace_token.surround(tokens, |tokens| {
3241                 inner_attrs_to_tokens(&self.attrs, tokens);
3242                 tokens.append_all(&self.block.stmts);
3243             });
3244         }
3245     }
3246 
3247     #[cfg(feature = "full")]
3248     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3249     impl ToTokens for ExprBlock {
to_tokens(&self, tokens: &mut TokenStream)3250         fn to_tokens(&self, tokens: &mut TokenStream) {
3251             outer_attrs_to_tokens(&self.attrs, tokens);
3252             self.label.to_tokens(tokens);
3253             self.block.brace_token.surround(tokens, |tokens| {
3254                 inner_attrs_to_tokens(&self.attrs, tokens);
3255                 tokens.append_all(&self.block.stmts);
3256             });
3257         }
3258     }
3259 
3260     #[cfg(feature = "full")]
3261     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3262     impl ToTokens for ExprAssign {
to_tokens(&self, tokens: &mut TokenStream)3263         fn to_tokens(&self, tokens: &mut TokenStream) {
3264             outer_attrs_to_tokens(&self.attrs, tokens);
3265             self.left.to_tokens(tokens);
3266             self.eq_token.to_tokens(tokens);
3267             self.right.to_tokens(tokens);
3268         }
3269     }
3270 
3271     #[cfg(feature = "full")]
3272     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3273     impl ToTokens for ExprAssignOp {
to_tokens(&self, tokens: &mut TokenStream)3274         fn to_tokens(&self, tokens: &mut TokenStream) {
3275             outer_attrs_to_tokens(&self.attrs, tokens);
3276             self.left.to_tokens(tokens);
3277             self.op.to_tokens(tokens);
3278             self.right.to_tokens(tokens);
3279         }
3280     }
3281 
3282     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3283     impl ToTokens for ExprField {
to_tokens(&self, tokens: &mut TokenStream)3284         fn to_tokens(&self, tokens: &mut TokenStream) {
3285             outer_attrs_to_tokens(&self.attrs, tokens);
3286             self.base.to_tokens(tokens);
3287             self.dot_token.to_tokens(tokens);
3288             self.member.to_tokens(tokens);
3289         }
3290     }
3291 
3292     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3293     impl ToTokens for Member {
to_tokens(&self, tokens: &mut TokenStream)3294         fn to_tokens(&self, tokens: &mut TokenStream) {
3295             match self {
3296                 Member::Named(ident) => ident.to_tokens(tokens),
3297                 Member::Unnamed(index) => index.to_tokens(tokens),
3298             }
3299         }
3300     }
3301 
3302     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3303     impl ToTokens for Index {
to_tokens(&self, tokens: &mut TokenStream)3304         fn to_tokens(&self, tokens: &mut TokenStream) {
3305             let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
3306             lit.set_span(self.span);
3307             tokens.append(lit);
3308         }
3309     }
3310 
3311     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3312     impl ToTokens for ExprIndex {
to_tokens(&self, tokens: &mut TokenStream)3313         fn to_tokens(&self, tokens: &mut TokenStream) {
3314             outer_attrs_to_tokens(&self.attrs, tokens);
3315             self.expr.to_tokens(tokens);
3316             self.bracket_token.surround(tokens, |tokens| {
3317                 self.index.to_tokens(tokens);
3318             });
3319         }
3320     }
3321 
3322     #[cfg(feature = "full")]
3323     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3324     impl ToTokens for ExprRange {
to_tokens(&self, tokens: &mut TokenStream)3325         fn to_tokens(&self, tokens: &mut TokenStream) {
3326             outer_attrs_to_tokens(&self.attrs, tokens);
3327             self.from.to_tokens(tokens);
3328             match &self.limits {
3329                 RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
3330                 RangeLimits::Closed(t) => t.to_tokens(tokens),
3331             }
3332             self.to.to_tokens(tokens);
3333         }
3334     }
3335 
3336     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3337     impl ToTokens for ExprPath {
to_tokens(&self, tokens: &mut TokenStream)3338         fn to_tokens(&self, tokens: &mut TokenStream) {
3339             outer_attrs_to_tokens(&self.attrs, tokens);
3340             private::print_path(tokens, &self.qself, &self.path);
3341         }
3342     }
3343 
3344     #[cfg(feature = "full")]
3345     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3346     impl ToTokens for ExprReference {
to_tokens(&self, tokens: &mut TokenStream)3347         fn to_tokens(&self, tokens: &mut TokenStream) {
3348             outer_attrs_to_tokens(&self.attrs, tokens);
3349             self.and_token.to_tokens(tokens);
3350             self.mutability.to_tokens(tokens);
3351             self.expr.to_tokens(tokens);
3352         }
3353     }
3354 
3355     #[cfg(feature = "full")]
3356     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3357     impl ToTokens for ExprBreak {
to_tokens(&self, tokens: &mut TokenStream)3358         fn to_tokens(&self, tokens: &mut TokenStream) {
3359             outer_attrs_to_tokens(&self.attrs, tokens);
3360             self.break_token.to_tokens(tokens);
3361             self.label.to_tokens(tokens);
3362             self.expr.to_tokens(tokens);
3363         }
3364     }
3365 
3366     #[cfg(feature = "full")]
3367     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3368     impl ToTokens for ExprContinue {
to_tokens(&self, tokens: &mut TokenStream)3369         fn to_tokens(&self, tokens: &mut TokenStream) {
3370             outer_attrs_to_tokens(&self.attrs, tokens);
3371             self.continue_token.to_tokens(tokens);
3372             self.label.to_tokens(tokens);
3373         }
3374     }
3375 
3376     #[cfg(feature = "full")]
3377     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3378     impl ToTokens for ExprReturn {
to_tokens(&self, tokens: &mut TokenStream)3379         fn to_tokens(&self, tokens: &mut TokenStream) {
3380             outer_attrs_to_tokens(&self.attrs, tokens);
3381             self.return_token.to_tokens(tokens);
3382             self.expr.to_tokens(tokens);
3383         }
3384     }
3385 
3386     #[cfg(feature = "full")]
3387     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3388     impl ToTokens for ExprMacro {
to_tokens(&self, tokens: &mut TokenStream)3389         fn to_tokens(&self, tokens: &mut TokenStream) {
3390             outer_attrs_to_tokens(&self.attrs, tokens);
3391             self.mac.to_tokens(tokens);
3392         }
3393     }
3394 
3395     #[cfg(feature = "full")]
3396     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3397     impl ToTokens for ExprStruct {
to_tokens(&self, tokens: &mut TokenStream)3398         fn to_tokens(&self, tokens: &mut TokenStream) {
3399             outer_attrs_to_tokens(&self.attrs, tokens);
3400             self.path.to_tokens(tokens);
3401             self.brace_token.surround(tokens, |tokens| {
3402                 inner_attrs_to_tokens(&self.attrs, tokens);
3403                 self.fields.to_tokens(tokens);
3404                 if let Some(dot2_token) = &self.dot2_token {
3405                     dot2_token.to_tokens(tokens);
3406                 } else if self.rest.is_some() {
3407                     Token![..](Span::call_site()).to_tokens(tokens);
3408                 }
3409                 self.rest.to_tokens(tokens);
3410             });
3411         }
3412     }
3413 
3414     #[cfg(feature = "full")]
3415     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3416     impl ToTokens for ExprRepeat {
to_tokens(&self, tokens: &mut TokenStream)3417         fn to_tokens(&self, tokens: &mut TokenStream) {
3418             outer_attrs_to_tokens(&self.attrs, tokens);
3419             self.bracket_token.surround(tokens, |tokens| {
3420                 inner_attrs_to_tokens(&self.attrs, tokens);
3421                 self.expr.to_tokens(tokens);
3422                 self.semi_token.to_tokens(tokens);
3423                 self.len.to_tokens(tokens);
3424             });
3425         }
3426     }
3427 
3428     #[cfg(feature = "full")]
3429     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3430     impl ToTokens for ExprGroup {
to_tokens(&self, tokens: &mut TokenStream)3431         fn to_tokens(&self, tokens: &mut TokenStream) {
3432             outer_attrs_to_tokens(&self.attrs, tokens);
3433             self.group_token.surround(tokens, |tokens| {
3434                 self.expr.to_tokens(tokens);
3435             });
3436         }
3437     }
3438 
3439     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3440     impl ToTokens for ExprParen {
to_tokens(&self, tokens: &mut TokenStream)3441         fn to_tokens(&self, tokens: &mut TokenStream) {
3442             outer_attrs_to_tokens(&self.attrs, tokens);
3443             self.paren_token.surround(tokens, |tokens| {
3444                 inner_attrs_to_tokens(&self.attrs, tokens);
3445                 self.expr.to_tokens(tokens);
3446             });
3447         }
3448     }
3449 
3450     #[cfg(feature = "full")]
3451     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3452     impl ToTokens for ExprTry {
to_tokens(&self, tokens: &mut TokenStream)3453         fn to_tokens(&self, tokens: &mut TokenStream) {
3454             outer_attrs_to_tokens(&self.attrs, tokens);
3455             self.expr.to_tokens(tokens);
3456             self.question_token.to_tokens(tokens);
3457         }
3458     }
3459 
3460     #[cfg(feature = "full")]
3461     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3462     impl ToTokens for Label {
to_tokens(&self, tokens: &mut TokenStream)3463         fn to_tokens(&self, tokens: &mut TokenStream) {
3464             self.name.to_tokens(tokens);
3465             self.colon_token.to_tokens(tokens);
3466         }
3467     }
3468 
3469     #[cfg(feature = "full")]
3470     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3471     impl ToTokens for FieldValue {
to_tokens(&self, tokens: &mut TokenStream)3472         fn to_tokens(&self, tokens: &mut TokenStream) {
3473             outer_attrs_to_tokens(&self.attrs, tokens);
3474             self.member.to_tokens(tokens);
3475             if let Some(colon_token) = &self.colon_token {
3476                 colon_token.to_tokens(tokens);
3477                 self.expr.to_tokens(tokens);
3478             }
3479         }
3480     }
3481 
3482     #[cfg(feature = "full")]
3483     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3484     impl ToTokens for Arm {
to_tokens(&self, tokens: &mut TokenStream)3485         fn to_tokens(&self, tokens: &mut TokenStream) {
3486             tokens.append_all(&self.attrs);
3487             self.pat.to_tokens(tokens);
3488             if let Some((if_token, guard)) = &self.guard {
3489                 if_token.to_tokens(tokens);
3490                 guard.to_tokens(tokens);
3491             }
3492             self.fat_arrow_token.to_tokens(tokens);
3493             self.body.to_tokens(tokens);
3494             self.comma.to_tokens(tokens);
3495         }
3496     }
3497 }
3498