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