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