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