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