1 use super::*;
2 use crate::punctuated::Punctuated;
3 #[cfg(feature = "extra-traits")]
4 use crate::tt::TokenStreamHelper;
5 use proc_macro2::{Span, TokenStream};
6 #[cfg(feature = "printing")]
7 use quote::IdentFragment;
8 #[cfg(feature = "printing")]
9 use std::fmt::{self, Display};
10 use std::hash::{Hash, Hasher};
11 #[cfg(all(feature = "parsing", feature = "full"))]
12 use std::mem;
13
14 ast_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
231 ast_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
242 ast_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
254 ast_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
266 ast_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
278 ast_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
290 ast_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
303 ast_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
314 ast_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
325 ast_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
338 ast_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
351 ast_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
364 ast_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
381 ast_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
392 ast_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
405 ast_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
420 ast_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
435 ast_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
452 ast_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
465 ast_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
478 ast_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
489 ast_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
501 ast_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
511 ast_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
524 ast_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
539 ast_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
550 ast_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
565 ast_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
577 ast_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
590 ast_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
603 ast_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
614 ast_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
631 ast_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
642 ast_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
653 ast_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
664 ast_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
676 ast_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
688 ast_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
699 ast_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
712 ast_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")]
724 impl Eq for Expr {}
725
726 #[cfg(feature = "extra-traits")]
727 impl PartialEq for Expr {
eq(&self, other: &Self) -> bool728 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")]
778 impl Hash for Expr {
hash<H>(&self, hash: &mut H) where H: Hasher,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
949 impl Expr {
950 #[cfg(all(feature = "parsing", feature = "full"))]
replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute>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
998 ast_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.*
1004 #[derive(Eq, PartialEq, Hash)]
1005 pub enum Member #manual_extra_traits {
1006 /// A named field like `self.x`.
1007 Named(Ident),
1008 /// An unnamed field like `self.0`.
1009 Unnamed(Index),
1010 }
1011 }
1012
1013 #[cfg(feature = "printing")]
1014 impl IdentFragment for Member {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result1015 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
span(&self) -> Option<Span>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
1030 ast_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
1041 impl From<usize> for Index {
from(index: usize) -> Index1042 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
1051 impl Eq for Index {}
1052
1053 impl PartialEq for Index {
eq(&self, other: &Self) -> bool1054 fn eq(&self, other: &Self) -> bool {
1055 self.index == other.index
1056 }
1057 }
1058
1059 impl Hash for Index {
hash<H: Hasher>(&self, state: &mut H)1060 fn hash<H: Hasher>(&self, state: &mut H) {
1061 self.index.hash(state);
1062 }
1063 }
1064
1065 #[cfg(feature = "printing")]
1066 impl IdentFragment for Index {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result1067 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1068 Display::fmt(&self.index, formatter)
1069 }
1070
span(&self) -> Option<Span>1071 fn span(&self) -> Option<Span> {
1072 Some(self.span)
1073 }
1074 }
1075
1076 #[cfg(feature = "full")]
1077 ast_struct! {
1078 #[derive(Default)]
1079 pub struct Reserved {
1080 _private: (),
1081 }
1082 }
1083
1084 #[cfg(feature = "full")]
1085 ast_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")]
1099 ast_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")]
1115 ast_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")]
1136 ast_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")]
1147 ast_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")]
1178 ast_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")]
requires_terminator(expr: &Expr) -> bool1193 pub(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")]
1210 pub(crate) mod parsing {
1211 use super::*;
1212
1213 use crate::parse::discouraged::Speculative;
1214 use crate::parse::{Parse, ParseStream, Result};
1215 use crate::path;
1216
1217 crate::custom_keyword!(raw);
1218
1219 // When we're parsing expressions which occur before blocks, like in an if
1220 // statement's condition, we cannot parse a struct literal.
1221 //
1222 // Struct literals are ambiguous in certain positions
1223 // https://github.com/rust-lang/rfcs/pull/92
1224 #[derive(Copy, Clone)]
1225 pub struct AllowStruct(bool);
1226
1227 #[derive(Copy, Clone, PartialEq, PartialOrd)]
1228 enum Precedence {
1229 Any,
1230 Assign,
1231 Range,
1232 Or,
1233 And,
1234 Compare,
1235 BitOr,
1236 BitXor,
1237 BitAnd,
1238 Shift,
1239 Arithmetic,
1240 Term,
1241 Cast,
1242 }
1243
1244 impl Precedence {
of(op: &BinOp) -> Self1245 fn of(op: &BinOp) -> Self {
1246 match *op {
1247 BinOp::Add(_) | BinOp::Sub(_) => Precedence::Arithmetic,
1248 BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Term,
1249 BinOp::And(_) => Precedence::And,
1250 BinOp::Or(_) => Precedence::Or,
1251 BinOp::BitXor(_) => Precedence::BitXor,
1252 BinOp::BitAnd(_) => Precedence::BitAnd,
1253 BinOp::BitOr(_) => Precedence::BitOr,
1254 BinOp::Shl(_) | BinOp::Shr(_) => Precedence::Shift,
1255 BinOp::Eq(_)
1256 | BinOp::Lt(_)
1257 | BinOp::Le(_)
1258 | BinOp::Ne(_)
1259 | BinOp::Ge(_)
1260 | BinOp::Gt(_) => Precedence::Compare,
1261 BinOp::AddEq(_)
1262 | BinOp::SubEq(_)
1263 | BinOp::MulEq(_)
1264 | BinOp::DivEq(_)
1265 | BinOp::RemEq(_)
1266 | BinOp::BitXorEq(_)
1267 | BinOp::BitAndEq(_)
1268 | BinOp::BitOrEq(_)
1269 | BinOp::ShlEq(_)
1270 | BinOp::ShrEq(_) => Precedence::Assign,
1271 }
1272 }
1273 }
1274
1275 impl Parse for Expr {
parse(input: ParseStream) -> Result<Self>1276 fn parse(input: ParseStream) -> Result<Self> {
1277 ambiguous_expr(input, AllowStruct(true))
1278 }
1279 }
1280
1281 #[cfg(feature = "full")]
expr_no_struct(input: ParseStream) -> Result<Expr>1282 fn expr_no_struct(input: ParseStream) -> Result<Expr> {
1283 ambiguous_expr(input, AllowStruct(false))
1284 }
1285
1286 #[cfg(feature = "full")]
parse_expr( input: ParseStream, mut lhs: Expr, allow_struct: AllowStruct, base: Precedence, ) -> Result<Expr>1287 fn parse_expr(
1288 input: ParseStream,
1289 mut lhs: Expr,
1290 allow_struct: AllowStruct,
1291 base: Precedence,
1292 ) -> Result<Expr> {
1293 loop {
1294 if input
1295 .fork()
1296 .parse::<BinOp>()
1297 .ok()
1298 .map_or(false, |op| Precedence::of(&op) >= base)
1299 {
1300 let op: BinOp = input.parse()?;
1301 let precedence = Precedence::of(&op);
1302 let mut rhs = unary_expr(input, allow_struct)?;
1303 loop {
1304 let next = peek_precedence(input);
1305 if next > precedence || next == precedence && precedence == Precedence::Assign {
1306 rhs = parse_expr(input, rhs, allow_struct, next)?;
1307 } else {
1308 break;
1309 }
1310 }
1311 lhs = if precedence == Precedence::Assign {
1312 Expr::AssignOp(ExprAssignOp {
1313 attrs: Vec::new(),
1314 left: Box::new(lhs),
1315 op,
1316 right: Box::new(rhs),
1317 })
1318 } else {
1319 Expr::Binary(ExprBinary {
1320 attrs: Vec::new(),
1321 left: Box::new(lhs),
1322 op,
1323 right: Box::new(rhs),
1324 })
1325 };
1326 } else if Precedence::Assign >= base
1327 && input.peek(Token![=])
1328 && !input.peek(Token![==])
1329 && !input.peek(Token![=>])
1330 {
1331 let eq_token: Token![=] = input.parse()?;
1332 let mut rhs = unary_expr(input, allow_struct)?;
1333 loop {
1334 let next = peek_precedence(input);
1335 if next >= Precedence::Assign {
1336 rhs = parse_expr(input, rhs, allow_struct, next)?;
1337 } else {
1338 break;
1339 }
1340 }
1341 lhs = Expr::Assign(ExprAssign {
1342 attrs: Vec::new(),
1343 left: Box::new(lhs),
1344 eq_token,
1345 right: Box::new(rhs),
1346 });
1347 } else if Precedence::Range >= base && input.peek(Token![..]) {
1348 let limits: RangeLimits = input.parse()?;
1349 let rhs = if input.is_empty()
1350 || input.peek(Token![,])
1351 || input.peek(Token![;])
1352 || !allow_struct.0 && input.peek(token::Brace)
1353 {
1354 None
1355 } else {
1356 let mut rhs = unary_expr(input, allow_struct)?;
1357 loop {
1358 let next = peek_precedence(input);
1359 if next > Precedence::Range {
1360 rhs = parse_expr(input, rhs, allow_struct, next)?;
1361 } else {
1362 break;
1363 }
1364 }
1365 Some(rhs)
1366 };
1367 lhs = Expr::Range(ExprRange {
1368 attrs: Vec::new(),
1369 from: Some(Box::new(lhs)),
1370 limits,
1371 to: rhs.map(Box::new),
1372 });
1373 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1374 let as_token: Token![as] = input.parse()?;
1375 let ty = input.call(Type::without_plus)?;
1376 lhs = Expr::Cast(ExprCast {
1377 attrs: Vec::new(),
1378 expr: Box::new(lhs),
1379 as_token,
1380 ty: Box::new(ty),
1381 });
1382 } else if Precedence::Cast >= base && input.peek(Token![:]) && !input.peek(Token![::]) {
1383 let colon_token: Token![:] = input.parse()?;
1384 let ty = input.call(Type::without_plus)?;
1385 lhs = Expr::Type(ExprType {
1386 attrs: Vec::new(),
1387 expr: Box::new(lhs),
1388 colon_token,
1389 ty: Box::new(ty),
1390 });
1391 } else {
1392 break;
1393 }
1394 }
1395 Ok(lhs)
1396 }
1397
1398 #[cfg(not(feature = "full"))]
parse_expr( input: ParseStream, mut lhs: Expr, allow_struct: AllowStruct, base: Precedence, ) -> Result<Expr>1399 fn parse_expr(
1400 input: ParseStream,
1401 mut lhs: Expr,
1402 allow_struct: AllowStruct,
1403 base: Precedence,
1404 ) -> Result<Expr> {
1405 loop {
1406 if input
1407 .fork()
1408 .parse::<BinOp>()
1409 .ok()
1410 .map_or(false, |op| Precedence::of(&op) >= base)
1411 {
1412 let op: BinOp = input.parse()?;
1413 let precedence = Precedence::of(&op);
1414 let mut rhs = unary_expr(input, allow_struct)?;
1415 loop {
1416 let next = peek_precedence(input);
1417 if next > precedence || next == precedence && precedence == Precedence::Assign {
1418 rhs = parse_expr(input, rhs, allow_struct, next)?;
1419 } else {
1420 break;
1421 }
1422 }
1423 lhs = Expr::Binary(ExprBinary {
1424 attrs: Vec::new(),
1425 left: Box::new(lhs),
1426 op,
1427 right: Box::new(rhs),
1428 });
1429 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1430 let as_token: Token![as] = input.parse()?;
1431 let ty = input.call(Type::without_plus)?;
1432 lhs = Expr::Cast(ExprCast {
1433 attrs: Vec::new(),
1434 expr: Box::new(lhs),
1435 as_token,
1436 ty: Box::new(ty),
1437 });
1438 } else {
1439 break;
1440 }
1441 }
1442 Ok(lhs)
1443 }
1444
peek_precedence(input: ParseStream) -> Precedence1445 fn peek_precedence(input: ParseStream) -> Precedence {
1446 if let Ok(op) = input.fork().parse() {
1447 Precedence::of(&op)
1448 } else if input.peek(Token![=]) && !input.peek(Token![=>]) {
1449 Precedence::Assign
1450 } else if input.peek(Token![..]) {
1451 Precedence::Range
1452 } else if input.peek(Token![as]) || input.peek(Token![:]) && !input.peek(Token![::]) {
1453 Precedence::Cast
1454 } else {
1455 Precedence::Any
1456 }
1457 }
1458
1459 // Parse an arbitrary expression.
ambiguous_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1460 fn ambiguous_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1461 let lhs = unary_expr(input, allow_struct)?;
1462 parse_expr(input, lhs, allow_struct, Precedence::Any)
1463 }
1464
1465 // <UnOp> <trailer>
1466 // & <trailer>
1467 // &mut <trailer>
1468 // box <trailer>
1469 #[cfg(feature = "full")]
unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1470 fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1471 let begin = input.fork();
1472 let ahead = input.fork();
1473 let attrs = ahead.call(Attribute::parse_outer)?;
1474 if ahead.peek(Token![&])
1475 || ahead.peek(Token![box])
1476 || ahead.peek(Token![*])
1477 || ahead.peek(Token![!])
1478 || ahead.peek(Token![-])
1479 {
1480 input.advance_to(&ahead);
1481 if input.peek(Token![&]) {
1482 let and_token: Token![&] = input.parse()?;
1483 let raw: Option<raw> = if input.peek(raw)
1484 && (input.peek2(Token![mut]) || input.peek2(Token![const]))
1485 {
1486 Some(input.parse()?)
1487 } else {
1488 None
1489 };
1490 let mutability: Option<Token![mut]> = input.parse()?;
1491 if raw.is_some() && mutability.is_none() {
1492 input.parse::<Token![const]>()?;
1493 }
1494 let expr = Box::new(unary_expr(input, allow_struct)?);
1495 if raw.is_some() {
1496 Ok(Expr::Verbatim(verbatim::between(begin, input)))
1497 } else {
1498 Ok(Expr::Reference(ExprReference {
1499 attrs,
1500 and_token,
1501 raw: Reserved::default(),
1502 mutability,
1503 expr,
1504 }))
1505 }
1506 } else if input.peek(Token![box]) {
1507 Ok(Expr::Box(ExprBox {
1508 attrs,
1509 box_token: input.parse()?,
1510 expr: Box::new(unary_expr(input, allow_struct)?),
1511 }))
1512 } else {
1513 Ok(Expr::Unary(ExprUnary {
1514 attrs,
1515 op: input.parse()?,
1516 expr: Box::new(unary_expr(input, allow_struct)?),
1517 }))
1518 }
1519 } else {
1520 trailer_expr(input, allow_struct)
1521 }
1522 }
1523
1524 #[cfg(not(feature = "full"))]
unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1525 fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1526 let ahead = input.fork();
1527 let attrs = ahead.call(Attribute::parse_outer)?;
1528 if ahead.peek(Token![*]) || ahead.peek(Token![!]) || ahead.peek(Token![-]) {
1529 input.advance_to(&ahead);
1530 Ok(Expr::Unary(ExprUnary {
1531 attrs,
1532 op: input.parse()?,
1533 expr: Box::new(unary_expr(input, allow_struct)?),
1534 }))
1535 } else {
1536 trailer_expr(input, allow_struct)
1537 }
1538 }
1539
1540 // <atom> (..<args>) ...
1541 // <atom> . <ident> (..<args>) ...
1542 // <atom> . <ident> ...
1543 // <atom> . <lit> ...
1544 // <atom> [ <expr> ] ...
1545 // <atom> ? ...
1546 #[cfg(feature = "full")]
trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1547 fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1548 if input.peek(token::Group) {
1549 return input.call(expr_group).map(Expr::Group);
1550 }
1551
1552 let outer_attrs = input.call(Attribute::parse_outer)?;
1553
1554 let atom = atom_expr(input, allow_struct)?;
1555 let mut e = trailer_helper(input, atom)?;
1556
1557 let inner_attrs = e.replace_attrs(Vec::new());
1558 let attrs = private::attrs(outer_attrs, inner_attrs);
1559 e.replace_attrs(attrs);
1560 Ok(e)
1561 }
1562
1563 #[cfg(feature = "full")]
trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr>1564 fn trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr> {
1565 loop {
1566 if input.peek(token::Paren) {
1567 let content;
1568 e = Expr::Call(ExprCall {
1569 attrs: Vec::new(),
1570 func: Box::new(e),
1571 paren_token: parenthesized!(content in input),
1572 args: content.parse_terminated(Expr::parse)?,
1573 });
1574 } else if input.peek(Token![.]) && !input.peek(Token![..]) {
1575 let dot_token: Token![.] = input.parse()?;
1576
1577 if input.peek(token::Await) {
1578 e = Expr::Await(ExprAwait {
1579 attrs: Vec::new(),
1580 base: Box::new(e),
1581 dot_token,
1582 await_token: input.parse()?,
1583 });
1584 continue;
1585 }
1586
1587 let member: Member = input.parse()?;
1588 let turbofish = if member.is_named() && input.peek(Token![::]) {
1589 Some(MethodTurbofish {
1590 colon2_token: input.parse()?,
1591 lt_token: input.parse()?,
1592 args: {
1593 let mut args = Punctuated::new();
1594 loop {
1595 if input.peek(Token![>]) {
1596 break;
1597 }
1598 let value = input.call(generic_method_argument)?;
1599 args.push_value(value);
1600 if input.peek(Token![>]) {
1601 break;
1602 }
1603 let punct = input.parse()?;
1604 args.push_punct(punct);
1605 }
1606 args
1607 },
1608 gt_token: input.parse()?,
1609 })
1610 } else {
1611 None
1612 };
1613
1614 if turbofish.is_some() || input.peek(token::Paren) {
1615 if let Member::Named(method) = member {
1616 let content;
1617 e = Expr::MethodCall(ExprMethodCall {
1618 attrs: Vec::new(),
1619 receiver: Box::new(e),
1620 dot_token,
1621 method,
1622 turbofish,
1623 paren_token: parenthesized!(content in input),
1624 args: content.parse_terminated(Expr::parse)?,
1625 });
1626 continue;
1627 }
1628 }
1629
1630 e = Expr::Field(ExprField {
1631 attrs: Vec::new(),
1632 base: Box::new(e),
1633 dot_token,
1634 member,
1635 });
1636 } else if input.peek(token::Bracket) {
1637 let content;
1638 e = Expr::Index(ExprIndex {
1639 attrs: Vec::new(),
1640 expr: Box::new(e),
1641 bracket_token: bracketed!(content in input),
1642 index: content.parse()?,
1643 });
1644 } else if input.peek(Token![?]) {
1645 e = Expr::Try(ExprTry {
1646 attrs: Vec::new(),
1647 expr: Box::new(e),
1648 question_token: input.parse()?,
1649 });
1650 } else {
1651 break;
1652 }
1653 }
1654 Ok(e)
1655 }
1656
1657 #[cfg(not(feature = "full"))]
trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1658 fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1659 let mut e = atom_expr(input, allow_struct)?;
1660
1661 loop {
1662 if input.peek(token::Paren) {
1663 let content;
1664 e = Expr::Call(ExprCall {
1665 attrs: Vec::new(),
1666 func: Box::new(e),
1667 paren_token: parenthesized!(content in input),
1668 args: content.parse_terminated(Expr::parse)?,
1669 });
1670 } else if input.peek(Token![.]) && !input.peek(Token![..]) && !input.peek2(token::Await)
1671 {
1672 e = Expr::Field(ExprField {
1673 attrs: Vec::new(),
1674 base: Box::new(e),
1675 dot_token: input.parse()?,
1676 member: input.parse()?,
1677 });
1678 } else if input.peek(token::Bracket) {
1679 let content;
1680 e = Expr::Index(ExprIndex {
1681 attrs: Vec::new(),
1682 expr: Box::new(e),
1683 bracket_token: bracketed!(content in input),
1684 index: content.parse()?,
1685 });
1686 } else {
1687 break;
1688 }
1689 }
1690
1691 Ok(e)
1692 }
1693
1694 // Parse all atomic expressions which don't have to worry about precedence
1695 // interactions, as they are fully contained.
1696 #[cfg(feature = "full")]
atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1697 fn atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1698 if input.peek(token::Group) {
1699 input.call(expr_group).map(Expr::Group)
1700 } else if input.peek(Lit) {
1701 input.parse().map(Expr::Lit)
1702 } else if input.peek(Token![async])
1703 && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace))
1704 {
1705 input.call(expr_async).map(Expr::Async)
1706 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1707 input.call(expr_try_block).map(Expr::TryBlock)
1708 } else if input.peek(Token![|])
1709 || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move]))
1710 || input.peek(Token![static])
1711 || input.peek(Token![move])
1712 {
1713 expr_closure(input, allow_struct).map(Expr::Closure)
1714 } else if input.peek(Ident)
1715 || input.peek(Token![::])
1716 || input.peek(Token![<])
1717 || input.peek(Token![self])
1718 || input.peek(Token![Self])
1719 || input.peek(Token![super])
1720 || input.peek(Token![extern])
1721 || input.peek(Token![crate])
1722 {
1723 path_or_macro_or_struct(input, allow_struct)
1724 } else if input.peek(token::Paren) {
1725 paren_or_tuple(input)
1726 } else if input.peek(Token![break]) {
1727 expr_break(input, allow_struct).map(Expr::Break)
1728 } else if input.peek(Token![continue]) {
1729 input.call(expr_continue).map(Expr::Continue)
1730 } else if input.peek(Token![return]) {
1731 expr_ret(input, allow_struct).map(Expr::Return)
1732 } else if input.peek(token::Bracket) {
1733 array_or_repeat(input)
1734 } else if input.peek(Token![let]) {
1735 input.call(expr_let).map(Expr::Let)
1736 } else if input.peek(Token![if]) {
1737 input.parse().map(Expr::If)
1738 } else if input.peek(Token![while]) {
1739 input.parse().map(Expr::While)
1740 } else if input.peek(Token![for]) {
1741 input.parse().map(Expr::ForLoop)
1742 } else if input.peek(Token![loop]) {
1743 input.parse().map(Expr::Loop)
1744 } else if input.peek(Token![match]) {
1745 input.parse().map(Expr::Match)
1746 } else if input.peek(Token![yield]) {
1747 input.call(expr_yield).map(Expr::Yield)
1748 } else if input.peek(Token![unsafe]) {
1749 input.call(expr_unsafe).map(Expr::Unsafe)
1750 } else if input.peek(token::Brace) {
1751 input.call(expr_block).map(Expr::Block)
1752 } else if input.peek(Token![..]) {
1753 expr_range(input, allow_struct).map(Expr::Range)
1754 } else if input.peek(Lifetime) {
1755 let the_label: Label = input.parse()?;
1756 let mut expr = if input.peek(Token![while]) {
1757 Expr::While(input.parse()?)
1758 } else if input.peek(Token![for]) {
1759 Expr::ForLoop(input.parse()?)
1760 } else if input.peek(Token![loop]) {
1761 Expr::Loop(input.parse()?)
1762 } else if input.peek(token::Brace) {
1763 Expr::Block(input.call(expr_block)?)
1764 } else {
1765 return Err(input.error("expected loop or block expression"));
1766 };
1767 match &mut expr {
1768 Expr::While(ExprWhile { label, .. })
1769 | Expr::ForLoop(ExprForLoop { label, .. })
1770 | Expr::Loop(ExprLoop { label, .. })
1771 | Expr::Block(ExprBlock { label, .. }) => *label = Some(the_label),
1772 _ => unreachable!(),
1773 }
1774 Ok(expr)
1775 } else {
1776 Err(input.error("expected expression"))
1777 }
1778 }
1779
1780 #[cfg(not(feature = "full"))]
atom_expr(input: ParseStream, _allow_struct: AllowStruct) -> Result<Expr>1781 fn atom_expr(input: ParseStream, _allow_struct: AllowStruct) -> Result<Expr> {
1782 if input.peek(Lit) {
1783 input.parse().map(Expr::Lit)
1784 } else if input.peek(token::Paren) {
1785 input.call(expr_paren).map(Expr::Paren)
1786 } else if input.peek(Ident)
1787 || input.peek(Token![::])
1788 || input.peek(Token![<])
1789 || input.peek(Token![self])
1790 || input.peek(Token![Self])
1791 || input.peek(Token![super])
1792 || input.peek(Token![extern])
1793 || input.peek(Token![crate])
1794 {
1795 input.parse().map(Expr::Path)
1796 } else {
1797 Err(input.error("unsupported expression; enable syn's features=[\"full\"]"))
1798 }
1799 }
1800
1801 #[cfg(feature = "full")]
path_or_macro_or_struct(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1802 fn path_or_macro_or_struct(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1803 let expr: ExprPath = input.parse()?;
1804 if expr.qself.is_some() {
1805 return Ok(Expr::Path(expr));
1806 }
1807
1808 if input.peek(Token![!]) && !input.peek(Token![!=]) {
1809 let mut contains_arguments = false;
1810 for segment in &expr.path.segments {
1811 match segment.arguments {
1812 PathArguments::None => {}
1813 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
1814 contains_arguments = true;
1815 }
1816 }
1817 }
1818
1819 if !contains_arguments {
1820 let bang_token: Token![!] = input.parse()?;
1821 let (delimiter, tokens) = mac::parse_delimiter(input)?;
1822 return Ok(Expr::Macro(ExprMacro {
1823 attrs: Vec::new(),
1824 mac: Macro {
1825 path: expr.path,
1826 bang_token,
1827 delimiter,
1828 tokens,
1829 },
1830 }));
1831 }
1832 }
1833
1834 if allow_struct.0 && input.peek(token::Brace) {
1835 let outer_attrs = Vec::new();
1836 expr_struct_helper(input, outer_attrs, expr.path).map(Expr::Struct)
1837 } else {
1838 Ok(Expr::Path(expr))
1839 }
1840 }
1841
1842 #[cfg(feature = "full")]
paren_or_tuple(input: ParseStream) -> Result<Expr>1843 fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
1844 let content;
1845 let paren_token = parenthesized!(content in input);
1846 let inner_attrs = content.call(Attribute::parse_inner)?;
1847 if content.is_empty() {
1848 return Ok(Expr::Tuple(ExprTuple {
1849 attrs: inner_attrs,
1850 paren_token,
1851 elems: Punctuated::new(),
1852 }));
1853 }
1854
1855 let first: Expr = content.parse()?;
1856 if content.is_empty() {
1857 return Ok(Expr::Paren(ExprParen {
1858 attrs: inner_attrs,
1859 paren_token,
1860 expr: Box::new(first),
1861 }));
1862 }
1863
1864 let mut elems = Punctuated::new();
1865 elems.push_value(first);
1866 while !content.is_empty() {
1867 let punct = content.parse()?;
1868 elems.push_punct(punct);
1869 if content.is_empty() {
1870 break;
1871 }
1872 let value = content.parse()?;
1873 elems.push_value(value);
1874 }
1875 Ok(Expr::Tuple(ExprTuple {
1876 attrs: inner_attrs,
1877 paren_token,
1878 elems,
1879 }))
1880 }
1881
1882 #[cfg(feature = "full")]
array_or_repeat(input: ParseStream) -> Result<Expr>1883 fn array_or_repeat(input: ParseStream) -> Result<Expr> {
1884 let content;
1885 let bracket_token = bracketed!(content in input);
1886 let inner_attrs = content.call(Attribute::parse_inner)?;
1887 if content.is_empty() {
1888 return Ok(Expr::Array(ExprArray {
1889 attrs: inner_attrs,
1890 bracket_token,
1891 elems: Punctuated::new(),
1892 }));
1893 }
1894
1895 let first: Expr = content.parse()?;
1896 if content.is_empty() || content.peek(Token![,]) {
1897 let mut elems = Punctuated::new();
1898 elems.push_value(first);
1899 while !content.is_empty() {
1900 let punct = content.parse()?;
1901 elems.push_punct(punct);
1902 if content.is_empty() {
1903 break;
1904 }
1905 let value = content.parse()?;
1906 elems.push_value(value);
1907 }
1908 Ok(Expr::Array(ExprArray {
1909 attrs: inner_attrs,
1910 bracket_token,
1911 elems,
1912 }))
1913 } else if content.peek(Token![;]) {
1914 let semi_token: Token![;] = content.parse()?;
1915 let len: Expr = content.parse()?;
1916 Ok(Expr::Repeat(ExprRepeat {
1917 attrs: inner_attrs,
1918 bracket_token,
1919 expr: Box::new(first),
1920 semi_token,
1921 len: Box::new(len),
1922 }))
1923 } else {
1924 Err(content.error("expected `,` or `;`"))
1925 }
1926 }
1927
1928 #[cfg(feature = "full")]
expr_early(input: ParseStream) -> Result<Expr>1929 pub(crate) fn expr_early(input: ParseStream) -> Result<Expr> {
1930 let mut attrs = input.call(Attribute::parse_outer)?;
1931 let mut expr = if input.peek(Token![if]) {
1932 Expr::If(input.parse()?)
1933 } else if input.peek(Token![while]) {
1934 Expr::While(input.parse()?)
1935 } else if input.peek(Token![for]) {
1936 Expr::ForLoop(input.parse()?)
1937 } else if input.peek(Token![loop]) {
1938 Expr::Loop(input.parse()?)
1939 } else if input.peek(Token![match]) {
1940 Expr::Match(input.parse()?)
1941 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1942 Expr::TryBlock(input.call(expr_try_block)?)
1943 } else if input.peek(Token![unsafe]) {
1944 Expr::Unsafe(input.call(expr_unsafe)?)
1945 } else if input.peek(token::Brace) {
1946 Expr::Block(input.call(expr_block)?)
1947 } else {
1948 let allow_struct = AllowStruct(true);
1949 let mut expr = unary_expr(input, allow_struct)?;
1950
1951 attrs.extend(expr.replace_attrs(Vec::new()));
1952 expr.replace_attrs(attrs);
1953
1954 return parse_expr(input, expr, allow_struct, Precedence::Any);
1955 };
1956
1957 if input.peek(Token![.]) && !input.peek(Token![..]) || input.peek(Token![?]) {
1958 expr = trailer_helper(input, expr)?;
1959
1960 attrs.extend(expr.replace_attrs(Vec::new()));
1961 expr.replace_attrs(attrs);
1962
1963 let allow_struct = AllowStruct(true);
1964 return parse_expr(input, expr, allow_struct, Precedence::Any);
1965 }
1966
1967 attrs.extend(expr.replace_attrs(Vec::new()));
1968 expr.replace_attrs(attrs);
1969 Ok(expr)
1970 }
1971
1972 impl Parse for ExprLit {
parse(input: ParseStream) -> Result<Self>1973 fn parse(input: ParseStream) -> Result<Self> {
1974 Ok(ExprLit {
1975 attrs: Vec::new(),
1976 lit: input.parse()?,
1977 })
1978 }
1979 }
1980
1981 #[cfg(feature = "full")]
expr_group(input: ParseStream) -> Result<ExprGroup>1982 fn expr_group(input: ParseStream) -> Result<ExprGroup> {
1983 let group = crate::group::parse_group(input)?;
1984 Ok(ExprGroup {
1985 attrs: Vec::new(),
1986 group_token: group.token,
1987 expr: group.content.parse()?,
1988 })
1989 }
1990
1991 #[cfg(not(feature = "full"))]
expr_paren(input: ParseStream) -> Result<ExprParen>1992 fn expr_paren(input: ParseStream) -> Result<ExprParen> {
1993 let content;
1994 Ok(ExprParen {
1995 attrs: Vec::new(),
1996 paren_token: parenthesized!(content in input),
1997 expr: content.parse()?,
1998 })
1999 }
2000
2001 #[cfg(feature = "full")]
generic_method_argument(input: ParseStream) -> Result<GenericMethodArgument>2002 fn generic_method_argument(input: ParseStream) -> Result<GenericMethodArgument> {
2003 // TODO parse const generics as well
2004 input.parse().map(GenericMethodArgument::Type)
2005 }
2006
2007 #[cfg(feature = "full")]
expr_let(input: ParseStream) -> Result<ExprLet>2008 fn expr_let(input: ParseStream) -> Result<ExprLet> {
2009 Ok(ExprLet {
2010 attrs: Vec::new(),
2011 let_token: input.parse()?,
2012 pat: {
2013 let leading_vert: Option<Token![|]> = input.parse()?;
2014 let pat: Pat = input.parse()?;
2015 if leading_vert.is_some()
2016 || input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=])
2017 {
2018 let mut cases = Punctuated::new();
2019 cases.push_value(pat);
2020 while input.peek(Token![|])
2021 && !input.peek(Token![||])
2022 && !input.peek(Token![|=])
2023 {
2024 let punct = input.parse()?;
2025 cases.push_punct(punct);
2026 let pat: Pat = input.parse()?;
2027 cases.push_value(pat);
2028 }
2029 Pat::Or(PatOr {
2030 attrs: Vec::new(),
2031 leading_vert,
2032 cases,
2033 })
2034 } else {
2035 pat
2036 }
2037 },
2038 eq_token: input.parse()?,
2039 expr: Box::new(input.call(expr_no_struct)?),
2040 })
2041 }
2042
2043 #[cfg(feature = "full")]
2044 impl Parse for ExprIf {
parse(input: ParseStream) -> Result<Self>2045 fn parse(input: ParseStream) -> Result<Self> {
2046 Ok(ExprIf {
2047 attrs: Vec::new(),
2048 if_token: input.parse()?,
2049 cond: Box::new(input.call(expr_no_struct)?),
2050 then_branch: input.parse()?,
2051 else_branch: {
2052 if input.peek(Token![else]) {
2053 Some(input.call(else_block)?)
2054 } else {
2055 None
2056 }
2057 },
2058 })
2059 }
2060 }
2061
2062 #[cfg(feature = "full")]
else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)>2063 fn else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)> {
2064 let else_token: Token![else] = input.parse()?;
2065
2066 let lookahead = input.lookahead1();
2067 let else_branch = if input.peek(Token![if]) {
2068 input.parse().map(Expr::If)?
2069 } else if input.peek(token::Brace) {
2070 Expr::Block(ExprBlock {
2071 attrs: Vec::new(),
2072 label: None,
2073 block: input.parse()?,
2074 })
2075 } else {
2076 return Err(lookahead.error());
2077 };
2078
2079 Ok((else_token, Box::new(else_branch)))
2080 }
2081
2082 #[cfg(feature = "full")]
2083 impl Parse for ExprForLoop {
parse(input: ParseStream) -> Result<Self>2084 fn parse(input: ParseStream) -> Result<Self> {
2085 let label: Option<Label> = input.parse()?;
2086 let for_token: Token![for] = input.parse()?;
2087
2088 let leading_vert: Option<Token![|]> = input.parse()?;
2089 let mut pat: Pat = input.parse()?;
2090 if leading_vert.is_some() || input.peek(Token![|]) {
2091 let mut cases = Punctuated::new();
2092 cases.push_value(pat);
2093 while input.peek(Token![|]) {
2094 let punct = input.parse()?;
2095 cases.push_punct(punct);
2096 let pat: Pat = input.parse()?;
2097 cases.push_value(pat);
2098 }
2099 pat = Pat::Or(PatOr {
2100 attrs: Vec::new(),
2101 leading_vert,
2102 cases,
2103 });
2104 }
2105
2106 let in_token: Token![in] = input.parse()?;
2107 let expr: Expr = input.call(expr_no_struct)?;
2108
2109 let content;
2110 let brace_token = braced!(content in input);
2111 let inner_attrs = content.call(Attribute::parse_inner)?;
2112 let stmts = content.call(Block::parse_within)?;
2113
2114 Ok(ExprForLoop {
2115 attrs: inner_attrs,
2116 label,
2117 for_token,
2118 pat,
2119 in_token,
2120 expr: Box::new(expr),
2121 body: Block { brace_token, stmts },
2122 })
2123 }
2124 }
2125
2126 #[cfg(feature = "full")]
2127 impl Parse for ExprLoop {
parse(input: ParseStream) -> Result<Self>2128 fn parse(input: ParseStream) -> Result<Self> {
2129 let label: Option<Label> = input.parse()?;
2130 let loop_token: Token![loop] = input.parse()?;
2131
2132 let content;
2133 let brace_token = braced!(content in input);
2134 let inner_attrs = content.call(Attribute::parse_inner)?;
2135 let stmts = content.call(Block::parse_within)?;
2136
2137 Ok(ExprLoop {
2138 attrs: inner_attrs,
2139 label,
2140 loop_token,
2141 body: Block { brace_token, stmts },
2142 })
2143 }
2144 }
2145
2146 #[cfg(feature = "full")]
2147 impl Parse for ExprMatch {
parse(input: ParseStream) -> Result<Self>2148 fn parse(input: ParseStream) -> Result<Self> {
2149 let match_token: Token![match] = input.parse()?;
2150 let expr = expr_no_struct(input)?;
2151
2152 let content;
2153 let brace_token = braced!(content in input);
2154 let inner_attrs = content.call(Attribute::parse_inner)?;
2155
2156 let mut arms = Vec::new();
2157 while !content.is_empty() {
2158 arms.push(content.call(Arm::parse)?);
2159 }
2160
2161 Ok(ExprMatch {
2162 attrs: inner_attrs,
2163 match_token,
2164 expr: Box::new(expr),
2165 brace_token,
2166 arms,
2167 })
2168 }
2169 }
2170
2171 macro_rules! impl_by_parsing_expr {
2172 (
2173 $(
2174 $expr_type:ty, $variant:ident, $msg:expr,
2175 )*
2176 ) => {
2177 $(
2178 #[cfg(all(feature = "full", feature = "printing"))]
2179 impl Parse for $expr_type {
2180 fn parse(input: ParseStream) -> Result<Self> {
2181 let mut expr: Expr = input.parse()?;
2182 loop {
2183 match expr {
2184 Expr::$variant(inner) => return Ok(inner),
2185 Expr::Group(next) => expr = *next.expr,
2186 _ => return Err(Error::new_spanned(expr, $msg)),
2187 }
2188 }
2189 }
2190 }
2191 )*
2192 };
2193 }
2194
2195 impl_by_parsing_expr! {
2196 ExprBox, Box, "expected box expression",
2197 ExprArray, Array, "expected slice literal expression",
2198 ExprCall, Call, "expected function call expression",
2199 ExprMethodCall, MethodCall, "expected method call expression",
2200 ExprTuple, Tuple, "expected tuple expression",
2201 ExprBinary, Binary, "expected binary operation",
2202 ExprUnary, Unary, "expected unary operation",
2203 ExprCast, Cast, "expected cast expression",
2204 ExprType, Type, "expected type ascription expression",
2205 ExprLet, Let, "expected let guard",
2206 ExprClosure, Closure, "expected closure expression",
2207 ExprUnsafe, Unsafe, "expected unsafe block",
2208 ExprBlock, Block, "expected blocked scope",
2209 ExprAssign, Assign, "expected assignment expression",
2210 ExprAssignOp, AssignOp, "expected compound assignment expression",
2211 ExprField, Field, "expected struct field access",
2212 ExprIndex, Index, "expected indexing expression",
2213 ExprRange, Range, "expected range expression",
2214 ExprReference, Reference, "expected referencing operation",
2215 ExprBreak, Break, "expected break expression",
2216 ExprContinue, Continue, "expected continue expression",
2217 ExprReturn, Return, "expected return expression",
2218 ExprMacro, Macro, "expected macro invocation expression",
2219 ExprStruct, Struct, "expected struct literal expression",
2220 ExprRepeat, Repeat, "expected array literal constructed from one repeated element",
2221 ExprParen, Paren, "expected parenthesized expression",
2222 ExprTry, Try, "expected try expression",
2223 ExprAsync, Async, "expected async block",
2224 ExprTryBlock, TryBlock, "expected try block",
2225 ExprYield, Yield, "expected yield expression",
2226 }
2227
2228 #[cfg(feature = "full")]
expr_try_block(input: ParseStream) -> Result<ExprTryBlock>2229 fn expr_try_block(input: ParseStream) -> Result<ExprTryBlock> {
2230 Ok(ExprTryBlock {
2231 attrs: Vec::new(),
2232 try_token: input.parse()?,
2233 block: input.parse()?,
2234 })
2235 }
2236
2237 #[cfg(feature = "full")]
expr_yield(input: ParseStream) -> Result<ExprYield>2238 fn expr_yield(input: ParseStream) -> Result<ExprYield> {
2239 Ok(ExprYield {
2240 attrs: Vec::new(),
2241 yield_token: input.parse()?,
2242 expr: {
2243 if !input.is_empty() && !input.peek(Token![,]) && !input.peek(Token![;]) {
2244 Some(input.parse()?)
2245 } else {
2246 None
2247 }
2248 },
2249 })
2250 }
2251
2252 #[cfg(feature = "full")]
expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure>2253 fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
2254 let asyncness: Option<Token![async]> = input.parse()?;
2255 let movability: Option<Token![static]> = if asyncness.is_none() {
2256 input.parse()?
2257 } else {
2258 None
2259 };
2260 let capture: Option<Token![move]> = input.parse()?;
2261 let or1_token: Token![|] = input.parse()?;
2262
2263 let mut inputs = Punctuated::new();
2264 loop {
2265 if input.peek(Token![|]) {
2266 break;
2267 }
2268 let value = closure_arg(input)?;
2269 inputs.push_value(value);
2270 if input.peek(Token![|]) {
2271 break;
2272 }
2273 let punct: Token![,] = input.parse()?;
2274 inputs.push_punct(punct);
2275 }
2276
2277 let or2_token: Token![|] = input.parse()?;
2278
2279 let (output, body) = if input.peek(Token![->]) {
2280 let arrow_token: Token![->] = input.parse()?;
2281 let ty: Type = input.parse()?;
2282 let body: Block = input.parse()?;
2283 let output = ReturnType::Type(arrow_token, Box::new(ty));
2284 let block = Expr::Block(ExprBlock {
2285 attrs: Vec::new(),
2286 label: None,
2287 block: body,
2288 });
2289 (output, block)
2290 } else {
2291 let body = ambiguous_expr(input, allow_struct)?;
2292 (ReturnType::Default, body)
2293 };
2294
2295 Ok(ExprClosure {
2296 attrs: Vec::new(),
2297 asyncness,
2298 movability,
2299 capture,
2300 or1_token,
2301 inputs,
2302 or2_token,
2303 output,
2304 body: Box::new(body),
2305 })
2306 }
2307
2308 #[cfg(feature = "full")]
expr_async(input: ParseStream) -> Result<ExprAsync>2309 fn expr_async(input: ParseStream) -> Result<ExprAsync> {
2310 Ok(ExprAsync {
2311 attrs: Vec::new(),
2312 async_token: input.parse()?,
2313 capture: input.parse()?,
2314 block: input.parse()?,
2315 })
2316 }
2317
2318 #[cfg(feature = "full")]
closure_arg(input: ParseStream) -> Result<Pat>2319 fn closure_arg(input: ParseStream) -> Result<Pat> {
2320 let attrs = input.call(Attribute::parse_outer)?;
2321 let mut pat: Pat = input.parse()?;
2322
2323 if input.peek(Token![:]) {
2324 Ok(Pat::Type(PatType {
2325 attrs,
2326 pat: Box::new(pat),
2327 colon_token: input.parse()?,
2328 ty: input.parse()?,
2329 }))
2330 } else {
2331 match &mut pat {
2332 Pat::Box(pat) => pat.attrs = attrs,
2333 Pat::Ident(pat) => pat.attrs = attrs,
2334 Pat::Lit(pat) => pat.attrs = attrs,
2335 Pat::Macro(pat) => pat.attrs = attrs,
2336 Pat::Or(pat) => pat.attrs = attrs,
2337 Pat::Path(pat) => pat.attrs = attrs,
2338 Pat::Range(pat) => pat.attrs = attrs,
2339 Pat::Reference(pat) => pat.attrs = attrs,
2340 Pat::Rest(pat) => pat.attrs = attrs,
2341 Pat::Slice(pat) => pat.attrs = attrs,
2342 Pat::Struct(pat) => pat.attrs = attrs,
2343 Pat::Tuple(pat) => pat.attrs = attrs,
2344 Pat::TupleStruct(pat) => pat.attrs = attrs,
2345 Pat::Type(_) => unreachable!(),
2346 Pat::Verbatim(_) => {}
2347 Pat::Wild(pat) => pat.attrs = attrs,
2348 Pat::__Nonexhaustive => unreachable!(),
2349 }
2350 Ok(pat)
2351 }
2352 }
2353
2354 #[cfg(feature = "full")]
2355 impl Parse for ExprWhile {
parse(input: ParseStream) -> Result<Self>2356 fn parse(input: ParseStream) -> Result<Self> {
2357 let label: Option<Label> = input.parse()?;
2358 let while_token: Token![while] = input.parse()?;
2359 let cond = expr_no_struct(input)?;
2360
2361 let content;
2362 let brace_token = braced!(content in input);
2363 let inner_attrs = content.call(Attribute::parse_inner)?;
2364 let stmts = content.call(Block::parse_within)?;
2365
2366 Ok(ExprWhile {
2367 attrs: inner_attrs,
2368 label,
2369 while_token,
2370 cond: Box::new(cond),
2371 body: Block { brace_token, stmts },
2372 })
2373 }
2374 }
2375
2376 #[cfg(feature = "full")]
2377 impl Parse for Label {
parse(input: ParseStream) -> Result<Self>2378 fn parse(input: ParseStream) -> Result<Self> {
2379 Ok(Label {
2380 name: input.parse()?,
2381 colon_token: input.parse()?,
2382 })
2383 }
2384 }
2385
2386 #[cfg(feature = "full")]
2387 impl Parse for Option<Label> {
parse(input: ParseStream) -> Result<Self>2388 fn parse(input: ParseStream) -> Result<Self> {
2389 if input.peek(Lifetime) {
2390 input.parse().map(Some)
2391 } else {
2392 Ok(None)
2393 }
2394 }
2395 }
2396
2397 #[cfg(feature = "full")]
expr_continue(input: ParseStream) -> Result<ExprContinue>2398 fn expr_continue(input: ParseStream) -> Result<ExprContinue> {
2399 Ok(ExprContinue {
2400 attrs: Vec::new(),
2401 continue_token: input.parse()?,
2402 label: input.parse()?,
2403 })
2404 }
2405
2406 #[cfg(feature = "full")]
expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak>2407 fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
2408 Ok(ExprBreak {
2409 attrs: Vec::new(),
2410 break_token: input.parse()?,
2411 label: input.parse()?,
2412 expr: {
2413 if input.is_empty()
2414 || input.peek(Token![,])
2415 || input.peek(Token![;])
2416 || !allow_struct.0 && input.peek(token::Brace)
2417 {
2418 None
2419 } else {
2420 let expr = ambiguous_expr(input, allow_struct)?;
2421 Some(Box::new(expr))
2422 }
2423 },
2424 })
2425 }
2426
2427 #[cfg(feature = "full")]
expr_ret(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn>2428 fn expr_ret(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn> {
2429 Ok(ExprReturn {
2430 attrs: Vec::new(),
2431 return_token: input.parse()?,
2432 expr: {
2433 if input.is_empty() || input.peek(Token![,]) || input.peek(Token![;]) {
2434 None
2435 } else {
2436 // NOTE: return is greedy and eats blocks after it even when in a
2437 // position where structs are not allowed, such as in if statement
2438 // conditions. For example:
2439 //
2440 // if return { println!("A") } {} // Prints "A"
2441 let expr = ambiguous_expr(input, allow_struct)?;
2442 Some(Box::new(expr))
2443 }
2444 },
2445 })
2446 }
2447
2448 #[cfg(feature = "full")]
2449 impl Parse for FieldValue {
parse(input: ParseStream) -> Result<Self>2450 fn parse(input: ParseStream) -> Result<Self> {
2451 let attrs = input.call(Attribute::parse_outer)?;
2452 let member: Member = input.parse()?;
2453 let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() {
2454 let colon_token: Token![:] = input.parse()?;
2455 let value: Expr = input.parse()?;
2456 (Some(colon_token), value)
2457 } else if let Member::Named(ident) = &member {
2458 let value = Expr::Path(ExprPath {
2459 attrs: Vec::new(),
2460 qself: None,
2461 path: Path::from(ident.clone()),
2462 });
2463 (None, value)
2464 } else {
2465 unreachable!()
2466 };
2467
2468 Ok(FieldValue {
2469 attrs,
2470 member,
2471 colon_token,
2472 expr: value,
2473 })
2474 }
2475 }
2476
2477 #[cfg(feature = "full")]
expr_struct_helper( input: ParseStream, outer_attrs: Vec<Attribute>, path: Path, ) -> Result<ExprStruct>2478 fn expr_struct_helper(
2479 input: ParseStream,
2480 outer_attrs: Vec<Attribute>,
2481 path: Path,
2482 ) -> Result<ExprStruct> {
2483 let content;
2484 let brace_token = braced!(content in input);
2485 let inner_attrs = content.call(Attribute::parse_inner)?;
2486 let attrs = private::attrs(outer_attrs, inner_attrs);
2487
2488 let mut fields = Punctuated::new();
2489 while !content.is_empty() {
2490 if content.peek(Token![..]) {
2491 return Ok(ExprStruct {
2492 attrs,
2493 brace_token,
2494 path,
2495 fields,
2496 dot2_token: Some(content.parse()?),
2497 rest: Some(Box::new(content.parse()?)),
2498 });
2499 }
2500
2501 fields.push(content.parse()?);
2502 if !content.peek(Token![,]) {
2503 break;
2504 }
2505 let punct: Token![,] = content.parse()?;
2506 fields.push_punct(punct);
2507 }
2508
2509 Ok(ExprStruct {
2510 attrs,
2511 brace_token,
2512 path,
2513 fields,
2514 dot2_token: None,
2515 rest: None,
2516 })
2517 }
2518
2519 #[cfg(feature = "full")]
expr_unsafe(input: ParseStream) -> Result<ExprUnsafe>2520 fn expr_unsafe(input: ParseStream) -> Result<ExprUnsafe> {
2521 let unsafe_token: Token![unsafe] = input.parse()?;
2522
2523 let content;
2524 let brace_token = braced!(content in input);
2525 let inner_attrs = content.call(Attribute::parse_inner)?;
2526 let stmts = content.call(Block::parse_within)?;
2527
2528 Ok(ExprUnsafe {
2529 attrs: inner_attrs,
2530 unsafe_token,
2531 block: Block { brace_token, stmts },
2532 })
2533 }
2534
2535 #[cfg(feature = "full")]
expr_block(input: ParseStream) -> Result<ExprBlock>2536 pub fn expr_block(input: ParseStream) -> Result<ExprBlock> {
2537 let label: Option<Label> = input.parse()?;
2538
2539 let content;
2540 let brace_token = braced!(content in input);
2541 let inner_attrs = content.call(Attribute::parse_inner)?;
2542 let stmts = content.call(Block::parse_within)?;
2543
2544 Ok(ExprBlock {
2545 attrs: inner_attrs,
2546 label,
2547 block: Block { brace_token, stmts },
2548 })
2549 }
2550
2551 #[cfg(feature = "full")]
expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange>2552 fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
2553 Ok(ExprRange {
2554 attrs: Vec::new(),
2555 from: None,
2556 limits: input.parse()?,
2557 to: {
2558 if input.is_empty()
2559 || input.peek(Token![,])
2560 || input.peek(Token![;])
2561 || !allow_struct.0 && input.peek(token::Brace)
2562 {
2563 None
2564 } else {
2565 let to = ambiguous_expr(input, allow_struct)?;
2566 Some(Box::new(to))
2567 }
2568 },
2569 })
2570 }
2571
2572 #[cfg(feature = "full")]
2573 impl Parse for RangeLimits {
parse(input: ParseStream) -> Result<Self>2574 fn parse(input: ParseStream) -> Result<Self> {
2575 let lookahead = input.lookahead1();
2576 if lookahead.peek(Token![..=]) {
2577 input.parse().map(RangeLimits::Closed)
2578 } else if lookahead.peek(Token![...]) {
2579 let dot3: Token![...] = input.parse()?;
2580 Ok(RangeLimits::Closed(Token![..=](dot3.spans)))
2581 } else if lookahead.peek(Token![..]) {
2582 input.parse().map(RangeLimits::HalfOpen)
2583 } else {
2584 Err(lookahead.error())
2585 }
2586 }
2587 }
2588
2589 impl Parse for ExprPath {
parse(input: ParseStream) -> Result<Self>2590 fn parse(input: ParseStream) -> Result<Self> {
2591 #[cfg(not(feature = "full"))]
2592 let attrs = Vec::new();
2593 #[cfg(feature = "full")]
2594 let attrs = input.call(Attribute::parse_outer)?;
2595
2596 let (qself, path) = path::parsing::qpath(input, true)?;
2597
2598 Ok(ExprPath { attrs, qself, path })
2599 }
2600 }
2601
2602 impl Parse for Member {
parse(input: ParseStream) -> Result<Self>2603 fn parse(input: ParseStream) -> Result<Self> {
2604 if input.peek(Ident) {
2605 input.parse().map(Member::Named)
2606 } else if input.peek(LitInt) {
2607 input.parse().map(Member::Unnamed)
2608 } else {
2609 Err(input.error("expected identifier or integer"))
2610 }
2611 }
2612 }
2613
2614 #[cfg(feature = "full")]
2615 impl Parse for Arm {
parse(input: ParseStream) -> Result<Arm>2616 fn parse(input: ParseStream) -> Result<Arm> {
2617 let requires_comma;
2618 Ok(Arm {
2619 attrs: input.call(Attribute::parse_outer)?,
2620 pat: {
2621 let leading_vert: Option<Token![|]> = input.parse()?;
2622 let pat: Pat = input.parse()?;
2623 if leading_vert.is_some() || input.peek(Token![|]) {
2624 let mut cases = Punctuated::new();
2625 cases.push_value(pat);
2626 while input.peek(Token![|]) {
2627 let punct = input.parse()?;
2628 cases.push_punct(punct);
2629 let pat: Pat = input.parse()?;
2630 cases.push_value(pat);
2631 }
2632 Pat::Or(PatOr {
2633 attrs: Vec::new(),
2634 leading_vert,
2635 cases,
2636 })
2637 } else {
2638 pat
2639 }
2640 },
2641 guard: {
2642 if input.peek(Token![if]) {
2643 let if_token: Token![if] = input.parse()?;
2644 let guard: Expr = input.parse()?;
2645 Some((if_token, Box::new(guard)))
2646 } else {
2647 None
2648 }
2649 },
2650 fat_arrow_token: input.parse()?,
2651 body: {
2652 let body = input.call(expr_early)?;
2653 requires_comma = requires_terminator(&body);
2654 Box::new(body)
2655 },
2656 comma: {
2657 if requires_comma && !input.is_empty() {
2658 Some(input.parse()?)
2659 } else {
2660 input.parse()?
2661 }
2662 },
2663 })
2664 }
2665 }
2666
2667 impl Parse for Index {
parse(input: ParseStream) -> Result<Self>2668 fn parse(input: ParseStream) -> Result<Self> {
2669 let lit: LitInt = input.parse()?;
2670 if lit.suffix().is_empty() {
2671 Ok(Index {
2672 index: lit
2673 .base10_digits()
2674 .parse()
2675 .map_err(|err| Error::new(lit.span(), err))?,
2676 span: lit.span(),
2677 })
2678 } else {
2679 Err(Error::new(lit.span(), "expected unsuffixed integer"))
2680 }
2681 }
2682 }
2683
2684 #[cfg(feature = "full")]
2685 impl Member {
is_named(&self) -> bool2686 fn is_named(&self) -> bool {
2687 match *self {
2688 Member::Named(_) => true,
2689 Member::Unnamed(_) => false,
2690 }
2691 }
2692 }
2693 }
2694
2695 #[cfg(feature = "printing")]
2696 pub(crate) mod printing {
2697 use super::*;
2698
2699 use proc_macro2::{Literal, TokenStream};
2700 use quote::{ToTokens, TokenStreamExt};
2701
2702 #[cfg(feature = "full")]
2703 use crate::attr::FilterAttrs;
2704 #[cfg(feature = "full")]
2705 use crate::print::TokensOrDefault;
2706
2707 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2708 // before appending it to `TokenStream`.
2709 #[cfg(feature = "full")]
wrap_bare_struct(tokens: &mut TokenStream, e: &Expr)2710 fn wrap_bare_struct(tokens: &mut TokenStream, e: &Expr) {
2711 if let Expr::Struct(_) = *e {
2712 token::Paren::default().surround(tokens, |tokens| {
2713 e.to_tokens(tokens);
2714 });
2715 } else {
2716 e.to_tokens(tokens);
2717 }
2718 }
2719
2720 #[cfg(feature = "full")]
outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream)2721 pub(crate) fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
2722 tokens.append_all(attrs.outer());
2723 }
2724
2725 #[cfg(feature = "full")]
inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream)2726 fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
2727 tokens.append_all(attrs.inner());
2728 }
2729
2730 #[cfg(not(feature = "full"))]
outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream)2731 pub(crate) fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
2732
2733 #[cfg(not(feature = "full"))]
inner_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream)2734 fn inner_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
2735
2736 #[cfg(feature = "full")]
2737 impl ToTokens for ExprBox {
to_tokens(&self, tokens: &mut TokenStream)2738 fn to_tokens(&self, tokens: &mut TokenStream) {
2739 outer_attrs_to_tokens(&self.attrs, tokens);
2740 self.box_token.to_tokens(tokens);
2741 self.expr.to_tokens(tokens);
2742 }
2743 }
2744
2745 #[cfg(feature = "full")]
2746 impl ToTokens for ExprArray {
to_tokens(&self, tokens: &mut TokenStream)2747 fn to_tokens(&self, tokens: &mut TokenStream) {
2748 outer_attrs_to_tokens(&self.attrs, tokens);
2749 self.bracket_token.surround(tokens, |tokens| {
2750 inner_attrs_to_tokens(&self.attrs, tokens);
2751 self.elems.to_tokens(tokens);
2752 })
2753 }
2754 }
2755
2756 impl ToTokens for ExprCall {
to_tokens(&self, tokens: &mut TokenStream)2757 fn to_tokens(&self, tokens: &mut TokenStream) {
2758 outer_attrs_to_tokens(&self.attrs, tokens);
2759 self.func.to_tokens(tokens);
2760 self.paren_token.surround(tokens, |tokens| {
2761 self.args.to_tokens(tokens);
2762 })
2763 }
2764 }
2765
2766 #[cfg(feature = "full")]
2767 impl ToTokens for ExprMethodCall {
to_tokens(&self, tokens: &mut TokenStream)2768 fn to_tokens(&self, tokens: &mut TokenStream) {
2769 outer_attrs_to_tokens(&self.attrs, tokens);
2770 self.receiver.to_tokens(tokens);
2771 self.dot_token.to_tokens(tokens);
2772 self.method.to_tokens(tokens);
2773 self.turbofish.to_tokens(tokens);
2774 self.paren_token.surround(tokens, |tokens| {
2775 self.args.to_tokens(tokens);
2776 });
2777 }
2778 }
2779
2780 #[cfg(feature = "full")]
2781 impl ToTokens for MethodTurbofish {
to_tokens(&self, tokens: &mut TokenStream)2782 fn to_tokens(&self, tokens: &mut TokenStream) {
2783 self.colon2_token.to_tokens(tokens);
2784 self.lt_token.to_tokens(tokens);
2785 self.args.to_tokens(tokens);
2786 self.gt_token.to_tokens(tokens);
2787 }
2788 }
2789
2790 #[cfg(feature = "full")]
2791 impl ToTokens for GenericMethodArgument {
to_tokens(&self, tokens: &mut TokenStream)2792 fn to_tokens(&self, tokens: &mut TokenStream) {
2793 match self {
2794 GenericMethodArgument::Type(t) => t.to_tokens(tokens),
2795 GenericMethodArgument::Const(c) => c.to_tokens(tokens),
2796 }
2797 }
2798 }
2799
2800 #[cfg(feature = "full")]
2801 impl ToTokens for ExprTuple {
to_tokens(&self, tokens: &mut TokenStream)2802 fn to_tokens(&self, tokens: &mut TokenStream) {
2803 outer_attrs_to_tokens(&self.attrs, tokens);
2804 self.paren_token.surround(tokens, |tokens| {
2805 inner_attrs_to_tokens(&self.attrs, tokens);
2806 self.elems.to_tokens(tokens);
2807 // If we only have one argument, we need a trailing comma to
2808 // distinguish ExprTuple from ExprParen.
2809 if self.elems.len() == 1 && !self.elems.trailing_punct() {
2810 <Token![,]>::default().to_tokens(tokens);
2811 }
2812 })
2813 }
2814 }
2815
2816 impl ToTokens for ExprBinary {
to_tokens(&self, tokens: &mut TokenStream)2817 fn to_tokens(&self, tokens: &mut TokenStream) {
2818 outer_attrs_to_tokens(&self.attrs, tokens);
2819 self.left.to_tokens(tokens);
2820 self.op.to_tokens(tokens);
2821 self.right.to_tokens(tokens);
2822 }
2823 }
2824
2825 impl ToTokens for ExprUnary {
to_tokens(&self, tokens: &mut TokenStream)2826 fn to_tokens(&self, tokens: &mut TokenStream) {
2827 outer_attrs_to_tokens(&self.attrs, tokens);
2828 self.op.to_tokens(tokens);
2829 self.expr.to_tokens(tokens);
2830 }
2831 }
2832
2833 impl ToTokens for ExprLit {
to_tokens(&self, tokens: &mut TokenStream)2834 fn to_tokens(&self, tokens: &mut TokenStream) {
2835 outer_attrs_to_tokens(&self.attrs, tokens);
2836 self.lit.to_tokens(tokens);
2837 }
2838 }
2839
2840 impl ToTokens for ExprCast {
to_tokens(&self, tokens: &mut TokenStream)2841 fn to_tokens(&self, tokens: &mut TokenStream) {
2842 outer_attrs_to_tokens(&self.attrs, tokens);
2843 self.expr.to_tokens(tokens);
2844 self.as_token.to_tokens(tokens);
2845 self.ty.to_tokens(tokens);
2846 }
2847 }
2848
2849 #[cfg(feature = "full")]
2850 impl ToTokens for ExprType {
to_tokens(&self, tokens: &mut TokenStream)2851 fn to_tokens(&self, tokens: &mut TokenStream) {
2852 outer_attrs_to_tokens(&self.attrs, tokens);
2853 self.expr.to_tokens(tokens);
2854 self.colon_token.to_tokens(tokens);
2855 self.ty.to_tokens(tokens);
2856 }
2857 }
2858
2859 #[cfg(feature = "full")]
maybe_wrap_else(tokens: &mut TokenStream, else_: &Option<(Token![else], Box<Expr>)>)2860 fn maybe_wrap_else(tokens: &mut TokenStream, else_: &Option<(Token![else], Box<Expr>)>) {
2861 if let Some((else_token, else_)) = else_ {
2862 else_token.to_tokens(tokens);
2863
2864 // If we are not one of the valid expressions to exist in an else
2865 // clause, wrap ourselves in a block.
2866 match **else_ {
2867 Expr::If(_) | Expr::Block(_) => {
2868 else_.to_tokens(tokens);
2869 }
2870 _ => {
2871 token::Brace::default().surround(tokens, |tokens| {
2872 else_.to_tokens(tokens);
2873 });
2874 }
2875 }
2876 }
2877 }
2878
2879 #[cfg(feature = "full")]
2880 impl ToTokens for ExprLet {
to_tokens(&self, tokens: &mut TokenStream)2881 fn to_tokens(&self, tokens: &mut TokenStream) {
2882 outer_attrs_to_tokens(&self.attrs, tokens);
2883 self.let_token.to_tokens(tokens);
2884 self.pat.to_tokens(tokens);
2885 self.eq_token.to_tokens(tokens);
2886 wrap_bare_struct(tokens, &self.expr);
2887 }
2888 }
2889
2890 #[cfg(feature = "full")]
2891 impl ToTokens for ExprIf {
to_tokens(&self, tokens: &mut TokenStream)2892 fn to_tokens(&self, tokens: &mut TokenStream) {
2893 outer_attrs_to_tokens(&self.attrs, tokens);
2894 self.if_token.to_tokens(tokens);
2895 wrap_bare_struct(tokens, &self.cond);
2896 self.then_branch.to_tokens(tokens);
2897 maybe_wrap_else(tokens, &self.else_branch);
2898 }
2899 }
2900
2901 #[cfg(feature = "full")]
2902 impl ToTokens for ExprWhile {
to_tokens(&self, tokens: &mut TokenStream)2903 fn to_tokens(&self, tokens: &mut TokenStream) {
2904 outer_attrs_to_tokens(&self.attrs, tokens);
2905 self.label.to_tokens(tokens);
2906 self.while_token.to_tokens(tokens);
2907 wrap_bare_struct(tokens, &self.cond);
2908 self.body.brace_token.surround(tokens, |tokens| {
2909 inner_attrs_to_tokens(&self.attrs, tokens);
2910 tokens.append_all(&self.body.stmts);
2911 });
2912 }
2913 }
2914
2915 #[cfg(feature = "full")]
2916 impl ToTokens for ExprForLoop {
to_tokens(&self, tokens: &mut TokenStream)2917 fn to_tokens(&self, tokens: &mut TokenStream) {
2918 outer_attrs_to_tokens(&self.attrs, tokens);
2919 self.label.to_tokens(tokens);
2920 self.for_token.to_tokens(tokens);
2921 self.pat.to_tokens(tokens);
2922 self.in_token.to_tokens(tokens);
2923 wrap_bare_struct(tokens, &self.expr);
2924 self.body.brace_token.surround(tokens, |tokens| {
2925 inner_attrs_to_tokens(&self.attrs, tokens);
2926 tokens.append_all(&self.body.stmts);
2927 });
2928 }
2929 }
2930
2931 #[cfg(feature = "full")]
2932 impl ToTokens for ExprLoop {
to_tokens(&self, tokens: &mut TokenStream)2933 fn to_tokens(&self, tokens: &mut TokenStream) {
2934 outer_attrs_to_tokens(&self.attrs, tokens);
2935 self.label.to_tokens(tokens);
2936 self.loop_token.to_tokens(tokens);
2937 self.body.brace_token.surround(tokens, |tokens| {
2938 inner_attrs_to_tokens(&self.attrs, tokens);
2939 tokens.append_all(&self.body.stmts);
2940 });
2941 }
2942 }
2943
2944 #[cfg(feature = "full")]
2945 impl ToTokens for ExprMatch {
to_tokens(&self, tokens: &mut TokenStream)2946 fn to_tokens(&self, tokens: &mut TokenStream) {
2947 outer_attrs_to_tokens(&self.attrs, tokens);
2948 self.match_token.to_tokens(tokens);
2949 wrap_bare_struct(tokens, &self.expr);
2950 self.brace_token.surround(tokens, |tokens| {
2951 inner_attrs_to_tokens(&self.attrs, tokens);
2952 for (i, arm) in self.arms.iter().enumerate() {
2953 arm.to_tokens(tokens);
2954 // Ensure that we have a comma after a non-block arm, except
2955 // for the last one.
2956 let is_last = i == self.arms.len() - 1;
2957 if !is_last && requires_terminator(&arm.body) && arm.comma.is_none() {
2958 <Token![,]>::default().to_tokens(tokens);
2959 }
2960 }
2961 });
2962 }
2963 }
2964
2965 #[cfg(feature = "full")]
2966 impl ToTokens for ExprAsync {
to_tokens(&self, tokens: &mut TokenStream)2967 fn to_tokens(&self, tokens: &mut TokenStream) {
2968 outer_attrs_to_tokens(&self.attrs, tokens);
2969 self.async_token.to_tokens(tokens);
2970 self.capture.to_tokens(tokens);
2971 self.block.to_tokens(tokens);
2972 }
2973 }
2974
2975 #[cfg(feature = "full")]
2976 impl ToTokens for ExprAwait {
to_tokens(&self, tokens: &mut TokenStream)2977 fn to_tokens(&self, tokens: &mut TokenStream) {
2978 outer_attrs_to_tokens(&self.attrs, tokens);
2979 self.base.to_tokens(tokens);
2980 self.dot_token.to_tokens(tokens);
2981 self.await_token.to_tokens(tokens);
2982 }
2983 }
2984
2985 #[cfg(feature = "full")]
2986 impl ToTokens for ExprTryBlock {
to_tokens(&self, tokens: &mut TokenStream)2987 fn to_tokens(&self, tokens: &mut TokenStream) {
2988 outer_attrs_to_tokens(&self.attrs, tokens);
2989 self.try_token.to_tokens(tokens);
2990 self.block.to_tokens(tokens);
2991 }
2992 }
2993
2994 #[cfg(feature = "full")]
2995 impl ToTokens for ExprYield {
to_tokens(&self, tokens: &mut TokenStream)2996 fn to_tokens(&self, tokens: &mut TokenStream) {
2997 outer_attrs_to_tokens(&self.attrs, tokens);
2998 self.yield_token.to_tokens(tokens);
2999 self.expr.to_tokens(tokens);
3000 }
3001 }
3002
3003 #[cfg(feature = "full")]
3004 impl ToTokens for ExprClosure {
to_tokens(&self, tokens: &mut TokenStream)3005 fn to_tokens(&self, tokens: &mut TokenStream) {
3006 outer_attrs_to_tokens(&self.attrs, tokens);
3007 self.asyncness.to_tokens(tokens);
3008 self.movability.to_tokens(tokens);
3009 self.capture.to_tokens(tokens);
3010 self.or1_token.to_tokens(tokens);
3011 self.inputs.to_tokens(tokens);
3012 self.or2_token.to_tokens(tokens);
3013 self.output.to_tokens(tokens);
3014 self.body.to_tokens(tokens);
3015 }
3016 }
3017
3018 #[cfg(feature = "full")]
3019 impl ToTokens for ExprUnsafe {
to_tokens(&self, tokens: &mut TokenStream)3020 fn to_tokens(&self, tokens: &mut TokenStream) {
3021 outer_attrs_to_tokens(&self.attrs, tokens);
3022 self.unsafe_token.to_tokens(tokens);
3023 self.block.brace_token.surround(tokens, |tokens| {
3024 inner_attrs_to_tokens(&self.attrs, tokens);
3025 tokens.append_all(&self.block.stmts);
3026 });
3027 }
3028 }
3029
3030 #[cfg(feature = "full")]
3031 impl ToTokens for ExprBlock {
to_tokens(&self, tokens: &mut TokenStream)3032 fn to_tokens(&self, tokens: &mut TokenStream) {
3033 outer_attrs_to_tokens(&self.attrs, tokens);
3034 self.label.to_tokens(tokens);
3035 self.block.brace_token.surround(tokens, |tokens| {
3036 inner_attrs_to_tokens(&self.attrs, tokens);
3037 tokens.append_all(&self.block.stmts);
3038 });
3039 }
3040 }
3041
3042 #[cfg(feature = "full")]
3043 impl ToTokens for ExprAssign {
to_tokens(&self, tokens: &mut TokenStream)3044 fn to_tokens(&self, tokens: &mut TokenStream) {
3045 outer_attrs_to_tokens(&self.attrs, tokens);
3046 self.left.to_tokens(tokens);
3047 self.eq_token.to_tokens(tokens);
3048 self.right.to_tokens(tokens);
3049 }
3050 }
3051
3052 #[cfg(feature = "full")]
3053 impl ToTokens for ExprAssignOp {
to_tokens(&self, tokens: &mut TokenStream)3054 fn to_tokens(&self, tokens: &mut TokenStream) {
3055 outer_attrs_to_tokens(&self.attrs, tokens);
3056 self.left.to_tokens(tokens);
3057 self.op.to_tokens(tokens);
3058 self.right.to_tokens(tokens);
3059 }
3060 }
3061
3062 impl ToTokens for ExprField {
to_tokens(&self, tokens: &mut TokenStream)3063 fn to_tokens(&self, tokens: &mut TokenStream) {
3064 outer_attrs_to_tokens(&self.attrs, tokens);
3065 self.base.to_tokens(tokens);
3066 self.dot_token.to_tokens(tokens);
3067 self.member.to_tokens(tokens);
3068 }
3069 }
3070
3071 impl ToTokens for Member {
to_tokens(&self, tokens: &mut TokenStream)3072 fn to_tokens(&self, tokens: &mut TokenStream) {
3073 match self {
3074 Member::Named(ident) => ident.to_tokens(tokens),
3075 Member::Unnamed(index) => index.to_tokens(tokens),
3076 }
3077 }
3078 }
3079
3080 impl ToTokens for Index {
to_tokens(&self, tokens: &mut TokenStream)3081 fn to_tokens(&self, tokens: &mut TokenStream) {
3082 let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
3083 lit.set_span(self.span);
3084 tokens.append(lit);
3085 }
3086 }
3087
3088 impl ToTokens for ExprIndex {
to_tokens(&self, tokens: &mut TokenStream)3089 fn to_tokens(&self, tokens: &mut TokenStream) {
3090 outer_attrs_to_tokens(&self.attrs, tokens);
3091 self.expr.to_tokens(tokens);
3092 self.bracket_token.surround(tokens, |tokens| {
3093 self.index.to_tokens(tokens);
3094 });
3095 }
3096 }
3097
3098 #[cfg(feature = "full")]
3099 impl ToTokens for ExprRange {
to_tokens(&self, tokens: &mut TokenStream)3100 fn to_tokens(&self, tokens: &mut TokenStream) {
3101 outer_attrs_to_tokens(&self.attrs, tokens);
3102 self.from.to_tokens(tokens);
3103 match &self.limits {
3104 RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
3105 RangeLimits::Closed(t) => t.to_tokens(tokens),
3106 }
3107 self.to.to_tokens(tokens);
3108 }
3109 }
3110
3111 impl ToTokens for ExprPath {
to_tokens(&self, tokens: &mut TokenStream)3112 fn to_tokens(&self, tokens: &mut TokenStream) {
3113 outer_attrs_to_tokens(&self.attrs, tokens);
3114 private::print_path(tokens, &self.qself, &self.path);
3115 }
3116 }
3117
3118 #[cfg(feature = "full")]
3119 impl ToTokens for ExprReference {
to_tokens(&self, tokens: &mut TokenStream)3120 fn to_tokens(&self, tokens: &mut TokenStream) {
3121 outer_attrs_to_tokens(&self.attrs, tokens);
3122 self.and_token.to_tokens(tokens);
3123 self.mutability.to_tokens(tokens);
3124 self.expr.to_tokens(tokens);
3125 }
3126 }
3127
3128 #[cfg(feature = "full")]
3129 impl ToTokens for ExprBreak {
to_tokens(&self, tokens: &mut TokenStream)3130 fn to_tokens(&self, tokens: &mut TokenStream) {
3131 outer_attrs_to_tokens(&self.attrs, tokens);
3132 self.break_token.to_tokens(tokens);
3133 self.label.to_tokens(tokens);
3134 self.expr.to_tokens(tokens);
3135 }
3136 }
3137
3138 #[cfg(feature = "full")]
3139 impl ToTokens for ExprContinue {
to_tokens(&self, tokens: &mut TokenStream)3140 fn to_tokens(&self, tokens: &mut TokenStream) {
3141 outer_attrs_to_tokens(&self.attrs, tokens);
3142 self.continue_token.to_tokens(tokens);
3143 self.label.to_tokens(tokens);
3144 }
3145 }
3146
3147 #[cfg(feature = "full")]
3148 impl ToTokens for ExprReturn {
to_tokens(&self, tokens: &mut TokenStream)3149 fn to_tokens(&self, tokens: &mut TokenStream) {
3150 outer_attrs_to_tokens(&self.attrs, tokens);
3151 self.return_token.to_tokens(tokens);
3152 self.expr.to_tokens(tokens);
3153 }
3154 }
3155
3156 #[cfg(feature = "full")]
3157 impl ToTokens for ExprMacro {
to_tokens(&self, tokens: &mut TokenStream)3158 fn to_tokens(&self, tokens: &mut TokenStream) {
3159 outer_attrs_to_tokens(&self.attrs, tokens);
3160 self.mac.to_tokens(tokens);
3161 }
3162 }
3163
3164 #[cfg(feature = "full")]
3165 impl ToTokens for ExprStruct {
to_tokens(&self, tokens: &mut TokenStream)3166 fn to_tokens(&self, tokens: &mut TokenStream) {
3167 outer_attrs_to_tokens(&self.attrs, tokens);
3168 self.path.to_tokens(tokens);
3169 self.brace_token.surround(tokens, |tokens| {
3170 inner_attrs_to_tokens(&self.attrs, tokens);
3171 self.fields.to_tokens(tokens);
3172 if self.rest.is_some() {
3173 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
3174 self.rest.to_tokens(tokens);
3175 }
3176 })
3177 }
3178 }
3179
3180 #[cfg(feature = "full")]
3181 impl ToTokens for ExprRepeat {
to_tokens(&self, tokens: &mut TokenStream)3182 fn to_tokens(&self, tokens: &mut TokenStream) {
3183 outer_attrs_to_tokens(&self.attrs, tokens);
3184 self.bracket_token.surround(tokens, |tokens| {
3185 inner_attrs_to_tokens(&self.attrs, tokens);
3186 self.expr.to_tokens(tokens);
3187 self.semi_token.to_tokens(tokens);
3188 self.len.to_tokens(tokens);
3189 })
3190 }
3191 }
3192
3193 #[cfg(feature = "full")]
3194 impl ToTokens for ExprGroup {
to_tokens(&self, tokens: &mut TokenStream)3195 fn to_tokens(&self, tokens: &mut TokenStream) {
3196 outer_attrs_to_tokens(&self.attrs, tokens);
3197 self.group_token.surround(tokens, |tokens| {
3198 self.expr.to_tokens(tokens);
3199 });
3200 }
3201 }
3202
3203 impl ToTokens for ExprParen {
to_tokens(&self, tokens: &mut TokenStream)3204 fn to_tokens(&self, tokens: &mut TokenStream) {
3205 outer_attrs_to_tokens(&self.attrs, tokens);
3206 self.paren_token.surround(tokens, |tokens| {
3207 inner_attrs_to_tokens(&self.attrs, tokens);
3208 self.expr.to_tokens(tokens);
3209 });
3210 }
3211 }
3212
3213 #[cfg(feature = "full")]
3214 impl ToTokens for ExprTry {
to_tokens(&self, tokens: &mut TokenStream)3215 fn to_tokens(&self, tokens: &mut TokenStream) {
3216 outer_attrs_to_tokens(&self.attrs, tokens);
3217 self.expr.to_tokens(tokens);
3218 self.question_token.to_tokens(tokens);
3219 }
3220 }
3221
3222 #[cfg(feature = "full")]
3223 impl ToTokens for Label {
to_tokens(&self, tokens: &mut TokenStream)3224 fn to_tokens(&self, tokens: &mut TokenStream) {
3225 self.name.to_tokens(tokens);
3226 self.colon_token.to_tokens(tokens);
3227 }
3228 }
3229
3230 #[cfg(feature = "full")]
3231 impl ToTokens for FieldValue {
to_tokens(&self, tokens: &mut TokenStream)3232 fn to_tokens(&self, tokens: &mut TokenStream) {
3233 outer_attrs_to_tokens(&self.attrs, tokens);
3234 self.member.to_tokens(tokens);
3235 if let Some(colon_token) = &self.colon_token {
3236 colon_token.to_tokens(tokens);
3237 self.expr.to_tokens(tokens);
3238 }
3239 }
3240 }
3241
3242 #[cfg(feature = "full")]
3243 impl ToTokens for Arm {
to_tokens(&self, tokens: &mut TokenStream)3244 fn to_tokens(&self, tokens: &mut TokenStream) {
3245 tokens.append_all(&self.attrs);
3246 self.pat.to_tokens(tokens);
3247 if let Some((if_token, guard)) = &self.guard {
3248 if_token.to_tokens(tokens);
3249 guard.to_tokens(tokens);
3250 }
3251 self.fat_arrow_token.to_tokens(tokens);
3252 self.body.to_tokens(tokens);
3253 self.comma.to_tokens(tokens);
3254 }
3255 }
3256 }
3257