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