1 // Copyright 2018 Syn Developers
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
10 use proc_macro2
::{Span, TokenStream}
;
11 use punctuated
::Punctuated
;
12 #[cfg(feature = "extra-traits")]
13 use std
::hash
::{Hash, Hasher}
;
14 #[cfg(all(feature = "parsing", feature = "full"))]
16 #[cfg(feature = "extra-traits")]
17 use tt
::TokenStreamHelper
;
19 ast_enum_of_structs
! {
20 /// A Rust expression.
22 /// *This type is available if Syn is built with the `"derive"` or `"full"`
25 /// # Syntax tree enums
27 /// This type is a syntax tree enum. In Syn this and other syntax tree enums
28 /// are designed to be traversed using the following rebinding idiom.
33 /// # fn example(expr: Expr) {
34 /// # const IGNORE: &str = stringify! {
35 /// let expr: Expr = /* ... */;
38 /// Expr::MethodCall(expr) => {
41 /// Expr::Cast(expr) => {
44 /// Expr::If(expr) => {
53 /// We begin with a variable `expr` of type `Expr` that has no fields
54 /// (because it is an enum), and by matching on it and rebinding a variable
55 /// with the same name `expr` we effectively imbue our variable with all of
56 /// the data fields provided by the variant that it turned out to be. So for
57 /// example above if we ended up in the `MethodCall` case then we get to use
58 /// `expr.receiver`, `expr.args` etc; if we ended up in the `If` case we get
59 /// to use `expr.cond`, `expr.then_branch`, `expr.else_branch`.
61 /// The pattern is similar if the input expression is borrowed:
66 /// # fn example(expr: &Expr) {
68 /// Expr::MethodCall(ref expr) => {
75 /// This approach avoids repeating the variant names twice on every line.
78 /// # use syn::{Expr, ExprMethodCall};
80 /// # fn example(expr: Expr) {
82 /// Expr::MethodCall(ExprMethodCall { method, args, .. }) => { // repetitive
89 /// In general, the name to which a syntax tree enum variant is bound should
90 /// be a suitable name for the complete syntax tree enum type.
93 /// # use syn::{Expr, ExprField};
95 /// # fn example(discriminant: &ExprField) {
96 /// // Binding is called `base` which is the name I would use if I were
97 /// // assigning `*discriminant.base` without an `if let`.
98 /// if let Expr::Tuple(ref base) = *discriminant.base {
103 /// A sign that you may not be choosing the right variable names is if you
104 /// see names getting repeated in your code, like accessing
105 /// `receiver.receiver` or `pat.pat` or `cond.cond`.
107 /// A box expression: `box f`.
109 /// *This type is available if Syn is built with the `"full"` feature.*
110 pub Box(ExprBox
#full {
111 pub attrs
: Vec
<Attribute
>,
112 pub box_token
: Token
![box],
116 /// A placement expression: `place <- value`.
118 /// *This type is available if Syn is built with the `"full"` feature.*
119 pub InPlace(ExprInPlace
#full {
120 pub attrs
: Vec
<Attribute
>,
121 pub place
: Box
<Expr
>,
122 pub arrow_token
: Token
![<-],
123 pub value
: Box
<Expr
>,
126 /// A slice literal expression: `[a, b, c, d]`.
128 /// *This type is available if Syn is built with the `"full"` feature.*
129 pub Array(ExprArray
#full {
130 pub attrs
: Vec
<Attribute
>,
131 pub bracket_token
: token
::Bracket
,
132 pub elems
: Punctuated
<Expr
, Token
![,]>,
135 /// A function call expression: `invoke(a, b)`.
137 /// *This type is available if Syn is built with the `"derive"` or
138 /// `"full"` feature.*
140 pub attrs
: Vec
<Attribute
>,
142 pub paren_token
: token
::Paren
,
143 pub args
: Punctuated
<Expr
, Token
![,]>,
146 /// A method call expression: `x.foo::<T>(a, b)`.
148 /// *This type is available if Syn is built with the `"full"` feature.*
149 pub MethodCall(ExprMethodCall
#full {
150 pub attrs
: Vec
<Attribute
>,
151 pub receiver
: Box
<Expr
>,
152 pub dot_token
: Token
![.],
154 pub turbofish
: Option
<MethodTurbofish
>,
155 pub paren_token
: token
::Paren
,
156 pub args
: Punctuated
<Expr
, Token
![,]>,
159 /// A tuple expression: `(a, b, c, d)`.
161 /// *This type is available if Syn is built with the `"full"` feature.*
162 pub Tuple(ExprTuple
#full {
163 pub attrs
: Vec
<Attribute
>,
164 pub paren_token
: token
::Paren
,
165 pub elems
: Punctuated
<Expr
, Token
![,]>,
168 /// A binary operation: `a + b`, `a * b`.
170 /// *This type is available if Syn is built with the `"derive"` or
171 /// `"full"` feature.*
172 pub Binary(ExprBinary
{
173 pub attrs
: Vec
<Attribute
>,
176 pub right
: Box
<Expr
>,
179 /// A unary operation: `!x`, `*x`.
181 /// *This type is available if Syn is built with the `"derive"` or
182 /// `"full"` feature.*
183 pub Unary(ExprUnary
{
184 pub attrs
: Vec
<Attribute
>,
189 /// A literal in place of an expression: `1`, `"foo"`.
191 /// *This type is available if Syn is built with the `"derive"` or
192 /// `"full"` feature.*
194 pub attrs
: Vec
<Attribute
>,
198 /// A cast expression: `foo as f64`.
200 /// *This type is available if Syn is built with the `"derive"` or
201 /// `"full"` feature.*
203 pub attrs
: Vec
<Attribute
>,
205 pub as_token
: Token
![as],
209 /// A type ascription expression: `foo: f64`.
211 /// *This type is available if Syn is built with the `"full"` feature.*
212 pub Type(ExprType
#full {
213 pub attrs
: Vec
<Attribute
>,
215 pub colon_token
: Token
![:],
219 /// A `let` guard: `let Some(x) = opt`.
221 /// *This type is available if Syn is built with the `"full"` feature.*
222 pub Let(ExprLet
#full {
223 pub attrs
: Vec
<Attribute
>,
224 pub let_token
: Token
![let],
225 pub pats
: Punctuated
<Pat
, Token
![|]>,
226 pub eq_token
: Token
![=],
230 /// An `if` expression with an optional `else` block: `if expr { ... }
233 /// The `else` branch expression may only be an `If` or `Block`
234 /// expression, not any of the other types of expression.
236 /// *This type is available if Syn is built with the `"full"` feature.*
237 pub If(ExprIf
#full {
238 pub attrs
: Vec
<Attribute
>,
239 pub if_token
: Token
![if],
241 pub then_branch
: Block
,
242 pub else_branch
: Option
<(Token
![else], Box
<Expr
>)>,
245 /// A while loop: `while expr { ... }`.
247 /// *This type is available if Syn is built with the `"full"` feature.*
248 pub While(ExprWhile
#full {
249 pub attrs
: Vec
<Attribute
>,
250 pub label
: Option
<Label
>,
251 pub while_token
: Token
![while],
256 /// A for loop: `for pat in expr { ... }`.
258 /// *This type is available if Syn is built with the `"full"` feature.*
259 pub ForLoop(ExprForLoop
#full {
260 pub attrs
: Vec
<Attribute
>,
261 pub label
: Option
<Label
>,
262 pub for_token
: Token
![for],
264 pub in_token
: Token
![in],
269 /// Conditionless loop: `loop { ... }`.
271 /// *This type is available if Syn is built with the `"full"` feature.*
272 pub Loop(ExprLoop
#full {
273 pub attrs
: Vec
<Attribute
>,
274 pub label
: Option
<Label
>,
275 pub loop_token
: Token
![loop],
279 /// A `match` expression: `match n { Some(n) => {}, None => {} }`.
281 /// *This type is available if Syn is built with the `"full"` feature.*
282 pub Match(ExprMatch
#full {
283 pub attrs
: Vec
<Attribute
>,
284 pub match_token
: Token
![match],
286 pub brace_token
: token
::Brace
,
290 /// A closure expression: `|a, b| a + b`.
292 /// *This type is available if Syn is built with the `"full"` feature.*
293 pub Closure(ExprClosure
#full {
294 pub attrs
: Vec
<Attribute
>,
295 pub asyncness
: Option
<Token
![async
]>,
296 pub movability
: Option
<Token
![static]>,
297 pub capture
: Option
<Token
![move]>,
298 pub or1_token
: Token
![|],
299 pub inputs
: Punctuated
<FnArg
, Token
![,]>,
300 pub or2_token
: Token
![|],
301 pub output
: ReturnType
,
305 /// An unsafe block: `unsafe { ... }`.
307 /// *This type is available if Syn is built with the `"full"` feature.*
308 pub Unsafe(ExprUnsafe
#full {
309 pub attrs
: Vec
<Attribute
>,
310 pub unsafe_token
: Token
![unsafe],
314 /// A blocked scope: `{ ... }`.
316 /// *This type is available if Syn is built with the `"full"` feature.*
317 pub Block(ExprBlock
#full {
318 pub attrs
: Vec
<Attribute
>,
319 pub label
: Option
<Label
>,
323 /// An assignment expression: `a = compute()`.
325 /// *This type is available if Syn is built with the `"full"` feature.*
326 pub Assign(ExprAssign
#full {
327 pub attrs
: Vec
<Attribute
>,
329 pub eq_token
: Token
![=],
330 pub right
: Box
<Expr
>,
333 /// A compound assignment expression: `counter += 1`.
335 /// *This type is available if Syn is built with the `"full"` feature.*
336 pub AssignOp(ExprAssignOp
#full {
337 pub attrs
: Vec
<Attribute
>,
340 pub right
: Box
<Expr
>,
343 /// Access of a named struct field (`obj.k`) or unnamed tuple struct
346 /// *This type is available if Syn is built with the `"full"` feature.*
347 pub Field(ExprField
{
348 pub attrs
: Vec
<Attribute
>,
350 pub dot_token
: Token
![.],
354 /// A square bracketed indexing expression: `vector[2]`.
356 /// *This type is available if Syn is built with the `"derive"` or
357 /// `"full"` feature.*
358 pub Index(ExprIndex
{
359 pub attrs
: Vec
<Attribute
>,
361 pub bracket_token
: token
::Bracket
,
362 pub index
: Box
<Expr
>,
365 /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`.
367 /// *This type is available if Syn is built with the `"full"` feature.*
368 pub Range(ExprRange
#full {
369 pub attrs
: Vec
<Attribute
>,
370 pub from
: Option
<Box
<Expr
>>,
371 pub limits
: RangeLimits
,
372 pub to
: Option
<Box
<Expr
>>,
375 /// A path like `std::mem::replace` possibly containing generic
376 /// parameters and a qualified self-type.
378 /// A plain identifier like `x` is a path of length 1.
380 /// *This type is available if Syn is built with the `"derive"` or
381 /// `"full"` feature.*
383 pub attrs
: Vec
<Attribute
>,
384 pub qself
: Option
<QSelf
>,
388 /// A referencing operation: `&a` or `&mut a`.
390 /// *This type is available if Syn is built with the `"full"` feature.*
391 pub Reference(ExprReference
#full {
392 pub attrs
: Vec
<Attribute
>,
393 pub and_token
: Token
![&],
394 pub mutability
: Option
<Token
![mut]>,
398 /// A `break`, with an optional label to break and an optional
401 /// *This type is available if Syn is built with the `"full"` feature.*
402 pub Break(ExprBreak
#full {
403 pub attrs
: Vec
<Attribute
>,
404 pub break_token
: Token
![break],
405 pub label
: Option
<Lifetime
>,
406 pub expr
: Option
<Box
<Expr
>>,
409 /// A `continue`, with an optional label.
411 /// *This type is available if Syn is built with the `"full"` feature.*
412 pub Continue(ExprContinue
#full {
413 pub attrs
: Vec
<Attribute
>,
414 pub continue_token
: Token
![continue],
415 pub label
: Option
<Lifetime
>,
418 /// A `return`, with an optional value to be returned.
420 /// *This type is available if Syn is built with the `"full"` feature.*
421 pub Return(ExprReturn
#full {
422 pub attrs
: Vec
<Attribute
>,
423 pub return_token
: Token
![return],
424 pub expr
: Option
<Box
<Expr
>>,
427 /// A macro invocation expression: `format!("{}", q)`.
429 /// *This type is available if Syn is built with the `"full"` feature.*
430 pub Macro(ExprMacro
#full {
431 pub attrs
: Vec
<Attribute
>,
435 /// A struct literal expression: `Point { x: 1, y: 1 }`.
437 /// The `rest` provides the value of the remaining fields as in `S { a:
438 /// 1, b: 1, ..rest }`.
440 /// *This type is available if Syn is built with the `"full"` feature.*
441 pub Struct(ExprStruct
#full {
442 pub attrs
: Vec
<Attribute
>,
444 pub brace_token
: token
::Brace
,
445 pub fields
: Punctuated
<FieldValue
, Token
![,]>,
446 pub dot2_token
: Option
<Token
![..]>,
447 pub rest
: Option
<Box
<Expr
>>,
450 /// An array literal constructed from one repeated element: `[0u8; N]`.
452 /// *This type is available if Syn is built with the `"full"` feature.*
453 pub Repeat(ExprRepeat
#full {
454 pub attrs
: Vec
<Attribute
>,
455 pub bracket_token
: token
::Bracket
,
457 pub semi_token
: Token
![;],
461 /// A parenthesized expression: `(a + b)`.
463 /// *This type is available if Syn is built with the `"full"` feature.*
464 pub Paren(ExprParen
{
465 pub attrs
: Vec
<Attribute
>,
466 pub paren_token
: token
::Paren
,
470 /// An expression contained within invisible delimiters.
472 /// This variant is important for faithfully representing the precedence
473 /// of expressions and is related to `None`-delimited spans in a
476 /// *This type is available if Syn is built with the `"full"` feature.*
477 pub Group(ExprGroup
#full {
478 pub attrs
: Vec
<Attribute
>,
479 pub group_token
: token
::Group
,
483 /// A try-expression: `expr?`.
485 /// *This type is available if Syn is built with the `"full"` feature.*
486 pub Try(ExprTry
#full {
487 pub attrs
: Vec
<Attribute
>,
489 pub question_token
: Token
![?
],
492 /// An async block: `async { ... }`.
494 /// *This type is available if Syn is built with the `"full"` feature.*
495 pub Async(ExprAsync
#full {
496 pub attrs
: Vec
<Attribute
>,
497 pub async_token
: Token
![async
],
498 pub capture
: Option
<Token
![move]>,
502 /// A try block: `try { ... }`.
504 /// *This type is available if Syn is built with the `"full"` feature.*
505 pub TryBlock(ExprTryBlock
#full {
506 pub attrs
: Vec
<Attribute
>,
507 pub try_token
: Token
![try
],
511 /// A yield expression: `yield expr`.
513 /// *This type is available if Syn is built with the `"full"` feature.*
514 pub Yield(ExprYield
#full {
515 pub attrs
: Vec
<Attribute
>,
516 pub yield_token
: Token
![yield],
517 pub expr
: Option
<Box
<Expr
>>,
520 /// Tokens in expression position not interpreted by Syn.
522 /// *This type is available if Syn is built with the `"derive"` or
523 /// `"full"` feature.*
524 pub Verbatim(ExprVerbatim
#manual_extra_traits {
525 pub tts
: TokenStream
,
530 #[cfg(feature = "extra-traits")]
531 impl Eq
for ExprVerbatim {}
533 #[cfg(feature = "extra-traits")]
534 impl PartialEq
for ExprVerbatim
{
535 fn eq(&self, other
: &Self) -> bool
{
536 TokenStreamHelper(&self.tts
) == TokenStreamHelper(&other
.tts
)
540 #[cfg(feature = "extra-traits")]
541 impl Hash
for ExprVerbatim
{
542 fn hash
<H
>(&self, state
: &mut H
)
546 TokenStreamHelper(&self.tts
).hash(state
);
551 #[cfg(all(feature = "parsing", feature = "full"))]
552 fn replace_attrs(&mut self, new
: Vec
<Attribute
>) -> Vec
<Attribute
> {
554 Expr
::Box(ExprBox { ref mut attrs, .. }
)
555 | Expr
::InPlace(ExprInPlace { ref mut attrs, .. }
)
556 | Expr
::Array(ExprArray { ref mut attrs, .. }
)
557 | Expr
::Call(ExprCall { ref mut attrs, .. }
)
558 | Expr
::MethodCall(ExprMethodCall { ref mut attrs, .. }
)
559 | Expr
::Tuple(ExprTuple { ref mut attrs, .. }
)
560 | Expr
::Binary(ExprBinary { ref mut attrs, .. }
)
561 | Expr
::Unary(ExprUnary { ref mut attrs, .. }
)
562 | Expr
::Lit(ExprLit { ref mut attrs, .. }
)
563 | Expr
::Cast(ExprCast { ref mut attrs, .. }
)
564 | Expr
::Type(ExprType { ref mut attrs, .. }
)
565 | Expr
::Let(ExprLet { ref mut attrs, .. }
)
566 | Expr
::If(ExprIf { ref mut attrs, .. }
)
567 | Expr
::While(ExprWhile { ref mut attrs, .. }
)
568 | Expr
::ForLoop(ExprForLoop { ref mut attrs, .. }
)
569 | Expr
::Loop(ExprLoop { ref mut attrs, .. }
)
570 | Expr
::Match(ExprMatch { ref mut attrs, .. }
)
571 | Expr
::Closure(ExprClosure { ref mut attrs, .. }
)
572 | Expr
::Unsafe(ExprUnsafe { ref mut attrs, .. }
)
573 | Expr
::Block(ExprBlock { ref mut attrs, .. }
)
574 | Expr
::Assign(ExprAssign { ref mut attrs, .. }
)
575 | Expr
::AssignOp(ExprAssignOp { ref mut attrs, .. }
)
576 | Expr
::Field(ExprField { ref mut attrs, .. }
)
577 | Expr
::Index(ExprIndex { ref mut attrs, .. }
)
578 | Expr
::Range(ExprRange { ref mut attrs, .. }
)
579 | Expr
::Path(ExprPath { ref mut attrs, .. }
)
580 | Expr
::Reference(ExprReference { ref mut attrs, .. }
)
581 | Expr
::Break(ExprBreak { ref mut attrs, .. }
)
582 | Expr
::Continue(ExprContinue { ref mut attrs, .. }
)
583 | Expr
::Return(ExprReturn { ref mut attrs, .. }
)
584 | Expr
::Macro(ExprMacro { ref mut attrs, .. }
)
585 | Expr
::Struct(ExprStruct { ref mut attrs, .. }
)
586 | Expr
::Repeat(ExprRepeat { ref mut attrs, .. }
)
587 | Expr
::Paren(ExprParen { ref mut attrs, .. }
)
588 | Expr
::Group(ExprGroup { ref mut attrs, .. }
)
589 | Expr
::Try(ExprTry { ref mut attrs, .. }
)
590 | Expr
::Async(ExprAsync { ref mut attrs, .. }
)
591 | Expr
::TryBlock(ExprTryBlock { ref mut attrs, .. }
)
592 | Expr
::Yield(ExprYield { ref mut attrs, .. }
) => mem
::replace(attrs
, new
),
593 Expr
::Verbatim(_
) => Vec
::new(),
599 /// A struct or tuple struct field accessed in a struct literal or field
602 /// *This type is available if Syn is built with the `"derive"` or `"full"`
605 /// A named field like `self.x`.
607 /// An unnamed field like `self.0`.
613 /// The index of an unnamed tuple struct field.
615 /// *This type is available if Syn is built with the `"derive"` or `"full"`
617 pub struct Index
#manual_extra_traits {
623 impl From
<usize> for Index
{
624 fn from(index
: usize) -> Index
{
625 assert
!(index
< u32::max_value() as usize);
628 span
: Span
::call_site(),
633 #[cfg(feature = "extra-traits")]
636 #[cfg(feature = "extra-traits")]
637 impl PartialEq
for Index
{
638 fn eq(&self, other
: &Self) -> bool
{
639 self.index
== other
.index
643 #[cfg(feature = "extra-traits")]
644 impl Hash
for Index
{
645 fn hash
<H
: Hasher
>(&self, state
: &mut H
) {
646 self.index
.hash(state
);
650 #[cfg(feature = "full")]
652 /// The `::<>` explicit type parameters passed to a method call:
653 /// `parse::<u64>()`.
655 /// *This type is available if Syn is built with the `"full"` feature.*
656 pub struct MethodTurbofish
{
657 pub colon2_token
: Token
![::],
658 pub lt_token
: Token
![<],
659 pub args
: Punctuated
<GenericMethodArgument
, Token
![,]>,
660 pub gt_token
: Token
![>],
664 #[cfg(feature = "full")]
666 /// An individual generic argument to a method, like `T`.
668 /// *This type is available if Syn is built with the `"full"` feature.*
669 pub enum GenericMethodArgument
{
672 /// A const expression. Must be inside of a block.
674 /// NOTE: Identity expressions are represented as Type arguments, as
675 /// they are indistinguishable syntactically.
680 #[cfg(feature = "full")]
682 /// A field-value pair in a struct literal.
684 /// *This type is available if Syn is built with the `"full"` feature.*
685 pub struct FieldValue
{
686 /// Attributes tagged on the field.
687 pub attrs
: Vec
<Attribute
>,
689 /// Name or index of the field.
692 /// The colon in `Struct { x: x }`. If written in shorthand like
693 /// `Struct { x }`, there is no colon.
694 pub colon_token
: Option
<Token
![:]>,
696 /// Value of the field.
701 #[cfg(feature = "full")]
703 /// A lifetime labeling a `for`, `while`, or `loop`.
705 /// *This type is available if Syn is built with the `"full"` feature.*
708 pub colon_token
: Token
![:],
712 #[cfg(feature = "full")]
714 /// A braced block containing Rust statements.
716 /// *This type is available if Syn is built with the `"full"` feature.*
718 pub brace_token
: token
::Brace
,
719 /// Statements in a block
720 pub stmts
: Vec
<Stmt
>,
724 #[cfg(feature = "full")]
726 /// A statement, usually ending in a semicolon.
728 /// *This type is available if Syn is built with the `"full"` feature.*
730 /// A local (let) binding.
733 /// An item definition.
736 /// Expr without trailing semicolon.
739 /// Expression with trailing semicolon.
740 Semi(Expr
, Token
![;]),
744 #[cfg(feature = "full")]
746 /// A local `let` binding: `let x: u64 = s.parse()?`.
748 /// *This type is available if Syn is built with the `"full"` feature.*
750 pub attrs
: Vec
<Attribute
>,
751 pub let_token
: Token
![let],
752 pub pats
: Punctuated
<Pat
, Token
![|]>,
753 pub ty
: Option
<(Token
![:], Box
<Type
>)>,
754 pub init
: Option
<(Token
![=], Box
<Expr
>)>,
755 pub semi_token
: Token
![;],
759 #[cfg(feature = "full")]
760 ast_enum_of_structs
! {
761 /// A pattern in a local binding, function signature, match expression, or
762 /// various other places.
764 /// *This type is available if Syn is built with the `"full"` feature.*
766 /// # Syntax tree enum
768 /// This type is a [syntax tree enum].
770 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
772 /// A pattern that matches any value: `_`.
774 /// *This type is available if Syn is built with the `"full"` feature.*
776 pub underscore_token
: Token
![_
],
779 /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
781 /// *This type is available if Syn is built with the `"full"` feature.*
783 pub by_ref
: Option
<Token
![ref]>,
784 pub mutability
: Option
<Token
![mut]>,
786 pub subpat
: Option
<(Token
![@
], Box
<Pat
>)>,
789 /// A struct or struct variant pattern: `Variant { x, y, .. }`.
791 /// *This type is available if Syn is built with the `"full"` feature.*
792 pub Struct(PatStruct
{
794 pub brace_token
: token
::Brace
,
795 pub fields
: Punctuated
<FieldPat
, Token
![,]>,
796 pub dot2_token
: Option
<Token
![..]>,
799 /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
801 /// *This type is available if Syn is built with the `"full"` feature.*
802 pub TupleStruct(PatTupleStruct
{
807 /// A path pattern like `Color::Red`, optionally qualified with a
810 /// Unquailfied path patterns can legally refer to variants, structs,
811 /// constants or associated constants. Quailfied path patterns like
812 /// `<A>::B::C` and `<A as Trait>::B::C` can only legally refer to
813 /// associated constants.
815 /// *This type is available if Syn is built with the `"full"` feature.*
817 pub qself
: Option
<QSelf
>,
821 /// A tuple pattern: `(a, b)`.
823 /// *This type is available if Syn is built with the `"full"` feature.*
825 pub paren_token
: token
::Paren
,
826 pub front
: Punctuated
<Pat
, Token
![,]>,
827 pub dot2_token
: Option
<Token
![..]>,
828 pub comma_token
: Option
<Token
![,]>,
829 pub back
: Punctuated
<Pat
, Token
![,]>,
832 /// A box pattern: `box v`.
834 /// *This type is available if Syn is built with the `"full"` feature.*
836 pub box_token
: Token
![box],
840 /// A reference pattern: `&mut (first, second)`.
842 /// *This type is available if Syn is built with the `"full"` feature.*
844 pub and_token
: Token
![&],
845 pub mutability
: Option
<Token
![mut]>,
849 /// A literal pattern: `0`.
851 /// This holds an `Expr` rather than a `Lit` because negative numbers
852 /// are represented as an `Expr::Unary`.
854 /// *This type is available if Syn is built with the `"full"` feature.*
859 /// A range pattern: `1..=2`.
861 /// *This type is available if Syn is built with the `"full"` feature.*
864 pub limits
: RangeLimits
,
868 /// A dynamically sized slice pattern: `[a, b, i.., y, z]`.
870 /// *This type is available if Syn is built with the `"full"` feature.*
872 pub bracket_token
: token
::Bracket
,
873 pub front
: Punctuated
<Pat
, Token
![,]>,
874 pub middle
: Option
<Box
<Pat
>>,
875 pub dot2_token
: Option
<Token
![..]>,
876 pub comma_token
: Option
<Token
![,]>,
877 pub back
: Punctuated
<Pat
, Token
![,]>,
880 /// A macro in expression position.
882 /// *This type is available if Syn is built with the `"full"` feature.*
887 /// Tokens in pattern position not interpreted by Syn.
889 /// *This type is available if Syn is built with the `"full"` feature.*
890 pub Verbatim(PatVerbatim
#manual_extra_traits {
891 pub tts
: TokenStream
,
896 #[cfg(all(feature = "full", feature = "extra-traits"))]
897 impl Eq
for PatVerbatim {}
899 #[cfg(all(feature = "full", feature = "extra-traits"))]
900 impl PartialEq
for PatVerbatim
{
901 fn eq(&self, other
: &Self) -> bool
{
902 TokenStreamHelper(&self.tts
) == TokenStreamHelper(&other
.tts
)
906 #[cfg(all(feature = "full", feature = "extra-traits"))]
907 impl Hash
for PatVerbatim
{
908 fn hash
<H
>(&self, state
: &mut H
)
912 TokenStreamHelper(&self.tts
).hash(state
);
916 #[cfg(feature = "full")]
918 /// One arm of a `match` expression: `0...10 => { return true; }`.
923 /// # fn f() -> bool {
936 /// *This type is available if Syn is built with the `"full"` feature.*
938 pub attrs
: Vec
<Attribute
>,
939 pub leading_vert
: Option
<Token
![|]>,
940 pub pats
: Punctuated
<Pat
, Token
![|]>,
941 pub guard
: Option
<(Token
![if], Box
<Expr
>)>,
942 pub fat_arrow_token
: Token
![=>],
944 pub comma
: Option
<Token
![,]>,
948 #[cfg(feature = "full")]
950 /// Limit types of a range, inclusive or exclusive.
952 /// *This type is available if Syn is built with the `"full"` feature.*
953 #[cfg_attr(feature = "clone-impls", derive(Copy))]
954 pub enum RangeLimits
{
955 /// Inclusive at the beginning, exclusive at the end.
956 HalfOpen(Token
![..]),
957 /// Inclusive at the beginning and end.
962 #[cfg(feature = "full")]
964 /// A single field in a struct pattern.
966 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated
967 /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token.
969 /// *This type is available if Syn is built with the `"full"` feature.*
970 pub struct FieldPat
{
971 pub attrs
: Vec
<Attribute
>,
973 pub colon_token
: Option
<Token
![:]>,
978 #[cfg(any(feature = "parsing", feature = "printing"))]
979 #[cfg(feature = "full")]
980 fn requires_terminator(expr
: &Expr
) -> bool
{
981 // see https://github.com/rust-lang/rust/blob/eb8f2586e/src/libsyntax/parse/classify.rs#L17-L37
991 | Expr
::TryBlock(..) => false,
996 #[cfg(feature = "parsing")]
1000 #[cfg(feature = "full")]
1002 use parse
::{Parse, ParseStream, Result}
;
1005 // When we're parsing expressions which occur before blocks, like in an if
1006 // statement's condition, we cannot parse a struct literal.
1008 // Struct literals are ambiguous in certain positions
1009 // https://github.com/rust-lang/rfcs/pull/92
1010 #[derive(Copy, Clone)]
1011 pub struct AllowStruct(bool
);
1013 #[derive(Copy, Clone, PartialEq, PartialOrd)]
1032 fn of(op
: &BinOp
) -> Self {
1034 BinOp
::Add(_
) | BinOp
::Sub(_
) => Precedence
::Arithmetic
,
1035 BinOp
::Mul(_
) | BinOp
::Div(_
) | BinOp
::Rem(_
) => Precedence
::Term
,
1036 BinOp
::And(_
) => Precedence
::And
,
1037 BinOp
::Or(_
) => Precedence
::Or
,
1038 BinOp
::BitXor(_
) => Precedence
::BitXor
,
1039 BinOp
::BitAnd(_
) => Precedence
::BitAnd
,
1040 BinOp
::BitOr(_
) => Precedence
::BitOr
,
1041 BinOp
::Shl(_
) | BinOp
::Shr(_
) => Precedence
::Shift
,
1047 | BinOp
::Gt(_
) => Precedence
::Compare
,
1053 | BinOp
::BitXorEq(_
)
1054 | BinOp
::BitAndEq(_
)
1057 | BinOp
::ShrEq(_
) => Precedence
::Assign
,
1062 impl Parse
for Expr
{
1063 fn parse(input
: ParseStream
) -> Result
<Self> {
1064 ambiguous_expr(input
, AllowStruct(true))
1068 #[cfg(feature = "full")]
1069 fn expr_no_struct(input
: ParseStream
) -> Result
<Expr
> {
1070 ambiguous_expr(input
, AllowStruct(false))
1073 #[cfg(feature = "full")]
1077 allow_struct
: AllowStruct
,
1085 .map_or(false, |op
| Precedence
::of(&op
) >= base
)
1087 let op
: BinOp
= input
.parse()?
;
1088 let precedence
= Precedence
::of(&op
);
1089 let mut rhs
= unary_expr(input
, allow_struct
)?
;
1091 let next
= peek_precedence(input
);
1092 if next
> precedence
|| next
== precedence
&& precedence
== Precedence
::Assign
{
1093 rhs
= parse_expr(input
, rhs
, allow_struct
, next
)?
;
1098 lhs
= if precedence
== Precedence
::Assign
{
1099 Expr
::AssignOp(ExprAssignOp
{
1101 left
: Box
::new(lhs
),
1103 right
: Box
::new(rhs
),
1106 Expr
::Binary(ExprBinary
{
1108 left
: Box
::new(lhs
),
1110 right
: Box
::new(rhs
),
1113 } else if Precedence
::Assign
>= base
1114 && input
.peek(Token
![=])
1115 && !input
.peek(Token
![==])
1116 && !input
.peek(Token
![=>])
1118 let eq_token
: Token
![=] = input
.parse()?
;
1119 let mut rhs
= unary_expr(input
, allow_struct
)?
;
1121 let next
= peek_precedence(input
);
1122 if next
>= Precedence
::Assign
{
1123 rhs
= parse_expr(input
, rhs
, allow_struct
, next
)?
;
1128 lhs
= Expr
::Assign(ExprAssign
{
1130 left
: Box
::new(lhs
),
1132 right
: Box
::new(rhs
),
1134 } else if Precedence
::Placement
>= base
&& input
.peek(Token
![<-]) {
1135 let arrow_token
: Token
![<-] = input
.parse()?
;
1136 let mut rhs
= unary_expr(input
, allow_struct
)?
;
1138 let next
= peek_precedence(input
);
1139 if next
> Precedence
::Placement
{
1140 rhs
= parse_expr(input
, rhs
, allow_struct
, next
)?
;
1145 lhs
= Expr
::InPlace(ExprInPlace
{
1147 place
: Box
::new(lhs
),
1148 arrow_token
: arrow_token
,
1149 value
: Box
::new(rhs
),
1151 } else if Precedence
::Range
>= base
&& input
.peek(Token
![..]) {
1152 let limits
: RangeLimits
= input
.parse()?
;
1153 let rhs
= if input
.is_empty()
1154 || input
.peek(Token
![,])
1155 || input
.peek(Token
![;])
1156 || !allow_struct
.0 && input
.peek(token
::Brace
)
1160 let mut rhs
= unary_expr(input
, allow_struct
)?
;
1162 let next
= peek_precedence(input
);
1163 if next
> Precedence
::Range
{
1164 rhs
= parse_expr(input
, rhs
, allow_struct
, next
)?
;
1171 lhs
= Expr
::Range(ExprRange
{
1173 from
: Some(Box
::new(lhs
)),
1175 to
: rhs
.map(Box
::new
),
1177 } else if Precedence
::Cast
>= base
&& input
.peek(Token
![as]) {
1178 let as_token
: Token
![as] = input
.parse()?
;
1179 let ty
= input
.call(Type
::without_plus
)?
;
1180 lhs
= Expr
::Cast(ExprCast
{
1182 expr
: Box
::new(lhs
),
1186 } else if Precedence
::Cast
>= base
&& input
.peek(Token
![:]) && !input
.peek(Token
![::]) {
1187 let colon_token
: Token
![:] = input
.parse()?
;
1188 let ty
= input
.call(Type
::without_plus
)?
;
1189 lhs
= Expr
::Type(ExprType
{
1191 expr
: Box
::new(lhs
),
1192 colon_token
: colon_token
,
1202 #[cfg(not(feature = "full"))]
1206 allow_struct
: AllowStruct
,
1214 .map_or(false, |op
| Precedence
::of(&op
) >= base
)
1216 let op
: BinOp
= input
.parse()?
;
1217 let precedence
= Precedence
::of(&op
);
1218 let mut rhs
= unary_expr(input
, allow_struct
)?
;
1220 let next
= peek_precedence(input
);
1221 if next
> precedence
|| next
== precedence
&& precedence
== Precedence
::Assign
{
1222 rhs
= parse_expr(input
, rhs
, allow_struct
, next
)?
;
1227 lhs
= Expr
::Binary(ExprBinary
{
1229 left
: Box
::new(lhs
),
1231 right
: Box
::new(rhs
),
1233 } else if Precedence
::Cast
>= base
&& input
.peek(Token
![as]) {
1234 let as_token
: Token
![as] = input
.parse()?
;
1235 let ty
= input
.call(Type
::without_plus
)?
;
1236 lhs
= Expr
::Cast(ExprCast
{
1238 expr
: Box
::new(lhs
),
1249 fn peek_precedence(input
: ParseStream
) -> Precedence
{
1250 if let Ok(op
) = input
.fork().parse() {
1252 } else if input
.peek(Token
![=]) && !input
.peek(Token
![=>]) {
1254 } else if input
.peek(Token
![<-]) {
1255 Precedence
::Placement
1256 } else if input
.peek(Token
![..]) {
1258 } else if input
.peek(Token
![as]) || input
.peek(Token
![:]) && !input
.peek(Token
![::]) {
1265 // Parse an arbitrary expression.
1266 fn ambiguous_expr(input
: ParseStream
, allow_struct
: AllowStruct
) -> Result
<Expr
> {
1267 let lhs
= unary_expr(input
, allow_struct
)?
;
1268 parse_expr(input
, lhs
, allow_struct
, Precedence
::Any
)
1275 #[cfg(feature = "full")]
1276 fn unary_expr(input
: ParseStream
, allow_struct
: AllowStruct
) -> Result
<Expr
> {
1277 let ahead
= input
.fork();
1278 ahead
.call(Attribute
::parse_outer
)?
;
1279 if ahead
.peek(Token
![&])
1280 || ahead
.peek(Token
![box])
1281 || ahead
.peek(Token
![*])
1282 || ahead
.peek(Token
![!])
1283 || ahead
.peek(Token
![-])
1285 let attrs
= input
.call(Attribute
::parse_outer
)?
;
1286 if input
.peek(Token
![&]) {
1287 Ok(Expr
::Reference(ExprReference
{
1289 and_token
: input
.parse()?
,
1290 mutability
: input
.parse()?
,
1291 expr
: Box
::new(unary_expr(input
, allow_struct
)?
),
1293 } else if input
.peek(Token
![box]) {
1294 Ok(Expr
::Box(ExprBox
{
1296 box_token
: input
.parse()?
,
1297 expr
: Box
::new(unary_expr(input
, allow_struct
)?
),
1300 Ok(Expr
::Unary(ExprUnary
{
1303 expr
: Box
::new(unary_expr(input
, allow_struct
)?
),
1307 trailer_expr(input
, allow_struct
)
1311 #[cfg(not(feature = "full"))]
1312 fn unary_expr(input
: ParseStream
, allow_struct
: AllowStruct
) -> Result
<Expr
> {
1313 let ahead
= input
.fork();
1314 ahead
.call(Attribute
::parse_outer
)?
;
1315 if ahead
.peek(Token
![*]) || ahead
.peek(Token
![!]) || ahead
.peek(Token
![-]) {
1316 Ok(Expr
::Unary(ExprUnary
{
1317 attrs
: input
.call(Attribute
::parse_outer
)?
,
1319 expr
: Box
::new(unary_expr(input
, allow_struct
)?
),
1322 trailer_expr(input
, allow_struct
)
1326 // <atom> (..<args>) ...
1327 // <atom> . <ident> (..<args>) ...
1328 // <atom> . <ident> ...
1329 // <atom> . <lit> ...
1330 // <atom> [ <expr> ] ...
1332 #[cfg(feature = "full")]
1333 fn trailer_expr(input
: ParseStream
, allow_struct
: AllowStruct
) -> Result
<Expr
> {
1334 if input
.peek(token
::Group
) {
1335 return input
.call(expr_group
).map(Expr
::Group
);
1338 let outer_attrs
= input
.call(Attribute
::parse_outer
)?
;
1340 let atom
= atom_expr(input
, allow_struct
)?
;
1341 let mut e
= trailer_helper(input
, atom
)?
;
1343 let inner_attrs
= e
.replace_attrs(Vec
::new());
1344 let attrs
= private
::attrs(outer_attrs
, inner_attrs
);
1345 e
.replace_attrs(attrs
);
1349 #[cfg(feature = "full")]
1350 fn trailer_helper(input
: ParseStream
, mut e
: Expr
) -> Result
<Expr
> {
1352 if input
.peek(token
::Paren
) {
1354 e
= Expr
::Call(ExprCall
{
1357 paren_token
: parenthesized
!(content
in input
),
1358 args
: content
.parse_terminated(Expr
::parse
)?
,
1360 } else if input
.peek(Token
![.]) && !input
.peek(Token
![..]) {
1361 let dot_token
: Token
![.] = input
.parse()?
;
1362 let member
: Member
= input
.parse()?
;
1363 let turbofish
= if member
.is_named() && input
.peek(Token
![::]) {
1364 Some(MethodTurbofish
{
1365 colon2_token
: input
.parse()?
,
1366 lt_token
: input
.parse()?
,
1368 let mut args
= Punctuated
::new();
1370 if input
.peek(Token
![>]) {
1373 let value
= input
.call(generic_method_argument
)?
;
1374 args
.push_value(value
);
1375 if input
.peek(Token
![>]) {
1378 let punct
= input
.parse()?
;
1379 args
.push_punct(punct
);
1383 gt_token
: input
.parse()?
,
1389 if turbofish
.is_some() || input
.peek(token
::Paren
) {
1390 if let Member
::Named(method
) = member
{
1392 e
= Expr
::MethodCall(ExprMethodCall
{
1394 receiver
: Box
::new(e
),
1395 dot_token
: dot_token
,
1397 turbofish
: turbofish
,
1398 paren_token
: parenthesized
!(content
in input
),
1399 args
: content
.parse_terminated(Expr
::parse
)?
,
1405 e
= Expr
::Field(ExprField
{
1408 dot_token
: dot_token
,
1411 } else if input
.peek(token
::Bracket
) {
1413 e
= Expr
::Index(ExprIndex
{
1416 bracket_token
: bracketed
!(content
in input
),
1417 index
: content
.parse()?
,
1419 } else if input
.peek(Token
![?
]) {
1420 e
= Expr
::Try(ExprTry
{
1423 question_token
: input
.parse()?
,
1432 #[cfg(not(feature = "full"))]
1433 fn trailer_expr(input
: ParseStream
, allow_struct
: AllowStruct
) -> Result
<Expr
> {
1434 let mut e
= atom_expr(input
, allow_struct
)?
;
1437 if input
.peek(token
::Paren
) {
1439 e
= Expr
::Call(ExprCall
{
1442 paren_token
: parenthesized
!(content
in input
),
1443 args
: content
.parse_terminated(Expr
::parse
)?
,
1445 } else if input
.peek(Token
![.]) {
1446 e
= Expr
::Field(ExprField
{
1449 dot_token
: input
.parse()?
,
1450 member
: input
.parse()?
,
1452 } else if input
.peek(token
::Bracket
) {
1454 e
= Expr
::Index(ExprIndex
{
1457 bracket_token
: bracketed
!(content
in input
),
1458 index
: content
.parse()?
,
1468 // Parse all atomic expressions which don't have to worry about precedence
1469 // interactions, as they are fully contained.
1470 #[cfg(feature = "full")]
1471 fn atom_expr(input
: ParseStream
, allow_struct
: AllowStruct
) -> Result
<Expr
> {
1472 if input
.peek(token
::Group
) {
1473 input
.call(expr_group
).map(Expr
::Group
)
1474 } else if input
.peek(Lit
) {
1475 input
.call(expr_lit
).map(Expr
::Lit
)
1476 } else if input
.peek(Token
![async
])
1477 && (input
.peek2(token
::Brace
) || input
.peek2(Token
![move]) && input
.peek3(token
::Brace
))
1479 input
.call(expr_async
).map(Expr
::Async
)
1480 } else if input
.peek(Token
![try
]) && input
.peek2(token
::Brace
) {
1481 input
.call(expr_try_block
).map(Expr
::TryBlock
)
1482 } else if input
.peek(Token
![|])
1483 || input
.peek(Token
![async
]) && (input
.peek2(Token
![|]) || input
.peek2(Token
![move]))
1484 || input
.peek(Token
![static])
1485 || input
.peek(Token
![move])
1487 expr_closure(input
, allow_struct
).map(Expr
::Closure
)
1488 } else if input
.peek(Ident
)
1489 || input
.peek(Token
![::])
1490 || input
.peek(Token
![<])
1491 || input
.peek(Token
![self])
1492 || input
.peek(Token
![Self])
1493 || input
.peek(Token
![super])
1494 || input
.peek(Token
![extern])
1495 || input
.peek(Token
![crate])
1497 path_or_macro_or_struct(input
, allow_struct
)
1498 } else if input
.peek(token
::Paren
) {
1499 paren_or_tuple(input
)
1500 } else if input
.peek(Token
![break]) {
1501 expr_break(input
, allow_struct
).map(Expr
::Break
)
1502 } else if input
.peek(Token
![continue]) {
1503 input
.call(expr_continue
).map(Expr
::Continue
)
1504 } else if input
.peek(Token
![return]) {
1505 expr_ret(input
, allow_struct
).map(Expr
::Return
)
1506 } else if input
.peek(token
::Bracket
) {
1507 array_or_repeat(input
)
1508 } else if input
.peek(Token
![let]) {
1509 input
.call(expr_let
).map(Expr
::Let
)
1510 } else if input
.peek(Token
![if]) {
1511 input
.call(expr_if
).map(Expr
::If
)
1512 } else if input
.peek(Token
![while]) {
1513 input
.call(expr_while
).map(Expr
::While
)
1514 } else if input
.peek(Token
![for]) {
1515 input
.call(expr_for_loop
).map(Expr
::ForLoop
)
1516 } else if input
.peek(Token
![loop]) {
1517 input
.call(expr_loop
).map(Expr
::Loop
)
1518 } else if input
.peek(Token
![match]) {
1519 input
.call(expr_match
).map(Expr
::Match
)
1520 } else if input
.peek(Token
![yield]) {
1521 input
.call(expr_yield
).map(Expr
::Yield
)
1522 } else if input
.peek(Token
![unsafe]) {
1523 input
.call(expr_unsafe
).map(Expr
::Unsafe
)
1524 } else if input
.peek(token
::Brace
) {
1525 input
.call(expr_block
).map(Expr
::Block
)
1526 } else if input
.peek(Token
![..]) {
1527 expr_range(input
, allow_struct
).map(Expr
::Range
)
1528 } else if input
.peek(Lifetime
) {
1529 let the_label
: Label
= input
.parse()?
;
1530 let mut expr
= if input
.peek(Token
![while]) {
1531 Expr
::While(input
.call(expr_while
)?
)
1532 } else if input
.peek(Token
![for]) {
1533 Expr
::ForLoop(input
.call(expr_for_loop
)?
)
1534 } else if input
.peek(Token
![loop]) {
1535 Expr
::Loop(input
.call(expr_loop
)?
)
1536 } else if input
.peek(token
::Brace
) {
1537 Expr
::Block(input
.call(expr_block
)?
)
1539 return Err(input
.error("expected loop or block expression"));
1542 Expr
::While(ExprWhile { ref mut label, .. }
)
1543 | Expr
::ForLoop(ExprForLoop { ref mut label, .. }
)
1544 | Expr
::Loop(ExprLoop { ref mut label, .. }
)
1545 | Expr
::Block(ExprBlock { ref mut label, .. }
) => *label
= Some(the_label
),
1546 _
=> unreachable
!(),
1550 Err(input
.error("expected expression"))
1554 #[cfg(not(feature = "full"))]
1555 fn atom_expr(input
: ParseStream
, _allow_struct
: AllowStruct
) -> Result
<Expr
> {
1556 if input
.peek(Lit
) {
1557 input
.call(expr_lit
).map(Expr
::Lit
)
1558 } else if input
.peek(token
::Paren
) {
1559 input
.call(expr_paren
).map(Expr
::Paren
)
1560 } else if input
.peek(Ident
)
1561 || input
.peek(Token
![::])
1562 || input
.peek(Token
![<])
1563 || input
.peek(Token
![self])
1564 || input
.peek(Token
![Self])
1565 || input
.peek(Token
![super])
1566 || input
.peek(Token
![extern])
1567 || input
.peek(Token
![crate])
1569 input
.parse().map(Expr
::Path
)
1571 Err(input
.error("unsupported expression; enable syn's features=[\"full\"]"))
1575 #[cfg(feature = "full")]
1576 fn path_or_macro_or_struct(input
: ParseStream
, allow_struct
: AllowStruct
) -> Result
<Expr
> {
1577 let expr
: ExprPath
= input
.parse()?
;
1578 if expr
.qself
.is_some() {
1579 return Ok(Expr
::Path(expr
));
1582 if input
.peek(Token
![!]) && !input
.peek(Token
![!=]) {
1583 let mut contains_arguments
= false;
1584 for segment
in &expr
.path
.segments
{
1585 match segment
.arguments
{
1586 PathArguments
::None
=> {}
1587 PathArguments
::AngleBracketed(_
) | PathArguments
::Parenthesized(_
) => {
1588 contains_arguments
= true;
1593 if !contains_arguments
{
1594 let bang_token
: Token
![!] = input
.parse()?
;
1595 let (delimiter
, tts
) = mac
::parse_delimiter(input
)?
;
1596 return Ok(Expr
::Macro(ExprMacro
{
1600 bang_token
: bang_token
,
1601 delimiter
: delimiter
,
1608 if allow_struct
.0 && input
.peek(token
::Brace
) {
1609 let outer_attrs
= Vec
::new();
1610 expr_struct_helper(input
, outer_attrs
, expr
.path
).map(Expr
::Struct
)
1612 Ok(Expr
::Path(expr
))
1616 #[cfg(feature = "full")]
1617 fn paren_or_tuple(input
: ParseStream
) -> Result
<Expr
> {
1619 let paren_token
= parenthesized
!(content
in input
);
1620 let inner_attrs
= content
.call(Attribute
::parse_inner
)?
;
1621 if content
.is_empty() {
1622 return Ok(Expr
::Tuple(ExprTuple
{
1624 paren_token
: paren_token
,
1625 elems
: Punctuated
::new(),
1629 let first
: Expr
= content
.parse()?
;
1630 if content
.is_empty() {
1631 return Ok(Expr
::Paren(ExprParen
{
1633 paren_token
: paren_token
,
1634 expr
: Box
::new(first
),
1638 let mut elems
= Punctuated
::new();
1639 elems
.push_value(first
);
1640 while !content
.is_empty() {
1641 let punct
= content
.parse()?
;
1642 elems
.push_punct(punct
);
1643 if content
.is_empty() {
1646 let value
= content
.parse()?
;
1647 elems
.push_value(value
);
1649 Ok(Expr
::Tuple(ExprTuple
{
1651 paren_token
: paren_token
,
1656 #[cfg(feature = "full")]
1657 fn array_or_repeat(input
: ParseStream
) -> Result
<Expr
> {
1659 let bracket_token
= bracketed
!(content
in input
);
1660 let inner_attrs
= content
.call(Attribute
::parse_inner
)?
;
1661 if content
.is_empty() {
1662 return Ok(Expr
::Array(ExprArray
{
1664 bracket_token
: bracket_token
,
1665 elems
: Punctuated
::new(),
1669 let first
: Expr
= content
.parse()?
;
1670 if content
.is_empty() || content
.peek(Token
![,]) {
1671 let mut elems
= Punctuated
::new();
1672 elems
.push_value(first
);
1673 while !content
.is_empty() {
1674 let punct
= content
.parse()?
;
1675 elems
.push_punct(punct
);
1676 if content
.is_empty() {
1679 let value
= content
.parse()?
;
1680 elems
.push_value(value
);
1682 Ok(Expr
::Array(ExprArray
{
1684 bracket_token
: bracket_token
,
1687 } else if content
.peek(Token
![;]) {
1688 let semi_token
: Token
![;] = content
.parse()?
;
1689 let len
: Expr
= content
.parse()?
;
1690 Ok(Expr
::Repeat(ExprRepeat
{
1692 bracket_token
: bracket_token
,
1693 expr
: Box
::new(first
),
1694 semi_token
: semi_token
,
1698 Err(content
.error("expected `,` or `;`"))
1702 #[cfg(feature = "full")]
1703 fn expr_early(input
: ParseStream
) -> Result
<Expr
> {
1704 let mut attrs
= input
.call(Attribute
::parse_outer
)?
;
1705 let mut expr
= if input
.peek(Token
![if]) {
1706 Expr
::If(input
.call(expr_if
)?
)
1707 } else if input
.peek(Token
![while]) {
1708 Expr
::While(input
.call(expr_while
)?
)
1709 } else if input
.peek(Token
![for]) {
1710 Expr
::ForLoop(input
.call(expr_for_loop
)?
)
1711 } else if input
.peek(Token
![loop]) {
1712 Expr
::Loop(input
.call(expr_loop
)?
)
1713 } else if input
.peek(Token
![match]) {
1714 Expr
::Match(input
.call(expr_match
)?
)
1715 } else if input
.peek(Token
![try
]) && input
.peek2(token
::Brace
) {
1716 Expr
::TryBlock(input
.call(expr_try_block
)?
)
1717 } else if input
.peek(Token
![unsafe]) {
1718 Expr
::Unsafe(input
.call(expr_unsafe
)?
)
1719 } else if input
.peek(token
::Brace
) {
1720 Expr
::Block(input
.call(expr_block
)?
)
1722 let allow_struct
= AllowStruct(true);
1723 let mut expr
= unary_expr(input
, allow_struct
)?
;
1725 attrs
.extend(expr
.replace_attrs(Vec
::new()));
1726 expr
.replace_attrs(attrs
);
1728 return parse_expr(input
, expr
, allow_struct
, Precedence
::Any
);
1731 if input
.peek(Token
![.]) || input
.peek(Token
![?
]) {
1732 expr
= trailer_helper(input
, expr
)?
;
1734 attrs
.extend(expr
.replace_attrs(Vec
::new()));
1735 expr
.replace_attrs(attrs
);
1737 let allow_struct
= AllowStruct(true);
1738 return parse_expr(input
, expr
, allow_struct
, Precedence
::Any
);
1741 attrs
.extend(expr
.replace_attrs(Vec
::new()));
1742 expr
.replace_attrs(attrs
);
1746 pub fn expr_lit(input
: ParseStream
) -> Result
<ExprLit
> {
1749 lit
: input
.parse()?
,
1753 #[cfg(feature = "full")]
1754 fn expr_group(input
: ParseStream
) -> Result
<ExprGroup
> {
1755 let group
= private
::parse_group(input
)?
;
1758 group_token
: group
.token
,
1759 expr
: group
.content
.parse()?
,
1763 #[cfg(not(feature = "full"))]
1764 fn expr_paren(input
: ParseStream
) -> Result
<ExprParen
> {
1768 paren_token
: parenthesized
!(content
in input
),
1769 expr
: content
.parse()?
,
1773 #[cfg(feature = "full")]
1774 fn generic_method_argument(input
: ParseStream
) -> Result
<GenericMethodArgument
> {
1775 // TODO parse const generics as well
1776 input
.parse().map(GenericMethodArgument
::Type
)
1779 #[cfg(feature = "full")]
1780 fn expr_let(input
: ParseStream
) -> Result
<ExprLet
> {
1783 let_token
: input
.parse()?
,
1785 let mut pats
= Punctuated
::new();
1786 let value
: Pat
= input
.parse()?
;
1787 pats
.push_value(value
);
1788 while input
.peek(Token
![|]) && !input
.peek(Token
![||]) && !input
.peek(Token
![|=]) {
1789 let punct
= input
.parse()?
;
1790 pats
.push_punct(punct
);
1791 let value
: Pat
= input
.parse()?
;
1792 pats
.push_value(value
);
1796 eq_token
: input
.parse()?
,
1797 expr
: Box
::new(input
.call(expr_no_struct
)?
),
1801 #[cfg(feature = "full")]
1802 fn expr_if(input
: ParseStream
) -> Result
<ExprIf
> {
1805 if_token
: input
.parse()?
,
1806 cond
: Box
::new(input
.call(expr_no_struct
)?
),
1807 then_branch
: input
.parse()?
,
1809 if input
.peek(Token
![else]) {
1810 Some(input
.call(else_block
)?
)
1818 #[cfg(feature = "full")]
1819 fn else_block(input
: ParseStream
) -> Result
<(Token
![else], Box
<Expr
>)> {
1820 let else_token
: Token
![else] = input
.parse()?
;
1822 let lookahead
= input
.lookahead1();
1823 let else_branch
= if input
.peek(Token
![if]) {
1824 input
.call(expr_if
).map(Expr
::If
)?
1825 } else if input
.peek(token
::Brace
) {
1826 Expr
::Block(ExprBlock
{
1829 block
: input
.parse()?
,
1832 return Err(lookahead
.error());
1835 Ok((else_token
, Box
::new(else_branch
)))
1838 #[cfg(feature = "full")]
1839 fn expr_for_loop(input
: ParseStream
) -> Result
<ExprForLoop
> {
1840 let label
: Option
<Label
> = input
.parse()?
;
1841 let for_token
: Token
![for] = input
.parse()?
;
1842 let pat
: Pat
= input
.parse()?
;
1843 let in_token
: Token
![in] = input
.parse()?
;
1844 let expr
: Expr
= input
.call(expr_no_struct
)?
;
1847 let brace_token
= braced
!(content
in input
);
1848 let inner_attrs
= content
.call(Attribute
::parse_inner
)?
;
1849 let stmts
= content
.call(Block
::parse_within
)?
;
1854 for_token
: for_token
,
1857 expr
: Box
::new(expr
),
1859 brace_token
: brace_token
,
1865 #[cfg(feature = "full")]
1866 fn expr_loop(input
: ParseStream
) -> Result
<ExprLoop
> {
1867 let label
: Option
<Label
> = input
.parse()?
;
1868 let loop_token
: Token
![loop] = input
.parse()?
;
1871 let brace_token
= braced
!(content
in input
);
1872 let inner_attrs
= content
.call(Attribute
::parse_inner
)?
;
1873 let stmts
= content
.call(Block
::parse_within
)?
;
1878 loop_token
: loop_token
,
1880 brace_token
: brace_token
,
1886 #[cfg(feature = "full")]
1887 fn expr_match(input
: ParseStream
) -> Result
<ExprMatch
> {
1888 let match_token
: Token
![match] = input
.parse()?
;
1889 let expr
= expr_no_struct(input
)?
;
1892 let brace_token
= braced
!(content
in input
);
1893 let inner_attrs
= content
.call(Attribute
::parse_inner
)?
;
1895 let mut arms
= Vec
::new();
1896 while !content
.is_empty() {
1897 arms
.push(content
.call(Arm
::parse
)?
);
1902 match_token
: match_token
,
1903 expr
: Box
::new(expr
),
1904 brace_token
: brace_token
,
1909 #[cfg(feature = "full")]
1910 fn expr_try_block(input
: ParseStream
) -> Result
<ExprTryBlock
> {
1913 try_token
: input
.parse()?
,
1914 block
: input
.parse()?
,
1918 #[cfg(feature = "full")]
1919 fn expr_yield(input
: ParseStream
) -> Result
<ExprYield
> {
1922 yield_token
: input
.parse()?
,
1924 if !input
.is_empty() && !input
.peek(Token
![,]) && !input
.peek(Token
![;]) {
1925 Some(input
.parse()?
)
1933 #[cfg(feature = "full")]
1934 fn expr_closure(input
: ParseStream
, allow_struct
: AllowStruct
) -> Result
<ExprClosure
> {
1935 let asyncness
: Option
<Token
![async
]> = input
.parse()?
;
1936 let movability
: Option
<Token
![static]> = if asyncness
.is_none() {
1941 let capture
: Option
<Token
![move]> = input
.parse()?
;
1942 let or1_token
: Token
![|] = input
.parse()?
;
1944 let mut inputs
= Punctuated
::new();
1946 if input
.peek(Token
![|]) {
1949 let value
= fn_arg(input
)?
;
1950 inputs
.push_value(value
);
1951 if input
.peek(Token
![|]) {
1954 let punct
: Token
![,] = input
.parse()?
;
1955 inputs
.push_punct(punct
);
1958 let or2_token
: Token
![|] = input
.parse()?
;
1960 let (output
, body
) = if input
.peek(Token
![->]) {
1961 let arrow_token
: Token
![->] = input
.parse()?
;
1962 let ty
: Type
= input
.parse()?
;
1963 let body
: Block
= input
.parse()?
;
1964 let output
= ReturnType
::Type(arrow_token
, Box
::new(ty
));
1965 let block
= Expr
::Block(ExprBlock
{
1972 let body
= ambiguous_expr(input
, allow_struct
)?
;
1973 (ReturnType
::Default
, body
)
1978 asyncness
: asyncness
,
1979 movability
: movability
,
1981 or1_token
: or1_token
,
1983 or2_token
: or2_token
,
1985 body
: Box
::new(body
),
1989 #[cfg(feature = "full")]
1990 fn expr_async(input
: ParseStream
) -> Result
<ExprAsync
> {
1993 async_token
: input
.parse()?
,
1994 capture
: input
.parse()?
,
1995 block
: input
.parse()?
,
1999 #[cfg(feature = "full")]
2000 fn fn_arg(input
: ParseStream
) -> Result
<FnArg
> {
2001 let pat
: Pat
= input
.parse()?
;
2003 if input
.peek(Token
![:]) {
2004 Ok(FnArg
::Captured(ArgCaptured
{
2006 colon_token
: input
.parse()?
,
2010 Ok(FnArg
::Inferred(pat
))
2014 #[cfg(feature = "full")]
2015 fn expr_while(input
: ParseStream
) -> Result
<ExprWhile
> {
2016 let label
: Option
<Label
> = input
.parse()?
;
2017 let while_token
: Token
![while] = input
.parse()?
;
2018 let cond
= expr_no_struct(input
)?
;
2021 let brace_token
= braced
!(content
in input
);
2022 let inner_attrs
= content
.call(Attribute
::parse_inner
)?
;
2023 let stmts
= content
.call(Block
::parse_within
)?
;
2028 while_token
: while_token
,
2029 cond
: Box
::new(cond
),
2031 brace_token
: brace_token
,
2037 #[cfg(feature = "full")]
2038 impl Parse
for Label
{
2039 fn parse(input
: ParseStream
) -> Result
<Self> {
2041 name
: input
.parse()?
,
2042 colon_token
: input
.parse()?
,
2047 #[cfg(feature = "full")]
2048 impl Parse
for Option
<Label
> {
2049 fn parse(input
: ParseStream
) -> Result
<Self> {
2050 if input
.peek(Lifetime
) {
2051 input
.parse().map(Some
)
2058 #[cfg(feature = "full")]
2059 fn expr_continue(input
: ParseStream
) -> Result
<ExprContinue
> {
2062 continue_token
: input
.parse()?
,
2063 label
: input
.parse()?
,
2067 #[cfg(feature = "full")]
2068 fn expr_break(input
: ParseStream
, allow_struct
: AllowStruct
) -> Result
<ExprBreak
> {
2071 break_token
: input
.parse()?
,
2072 label
: input
.parse()?
,
2075 || input
.peek(Token
![,])
2076 || input
.peek(Token
![;])
2077 || !allow_struct
.0 && input
.peek(token
::Brace
)
2081 let expr
= ambiguous_expr(input
, allow_struct
)?
;
2082 Some(Box
::new(expr
))
2088 #[cfg(feature = "full")]
2089 fn expr_ret(input
: ParseStream
, allow_struct
: AllowStruct
) -> Result
<ExprReturn
> {
2092 return_token
: input
.parse()?
,
2094 if input
.is_empty() || input
.peek(Token
![,]) || input
.peek(Token
![;]) {
2097 // NOTE: return is greedy and eats blocks after it even when in a
2098 // position where structs are not allowed, such as in if statement
2099 // conditions. For example:
2101 // if return { println!("A") } {} // Prints "A"
2102 let expr
= ambiguous_expr(input
, allow_struct
)?
;
2103 Some(Box
::new(expr
))
2109 #[cfg(feature = "full")]
2110 impl Parse
for FieldValue
{
2111 fn parse(input
: ParseStream
) -> Result
<Self> {
2112 let member
: Member
= input
.parse()?
;
2113 let (colon_token
, value
) = if input
.peek(Token
![:]) || !member
.is_named() {
2114 let colon_token
: Token
![:] = input
.parse()?
;
2115 let value
: Expr
= input
.parse()?
;
2116 (Some(colon_token
), value
)
2117 } else if let Member
::Named(ref ident
) = member
{
2118 let value
= Expr
::Path(ExprPath
{
2121 path
: Path
::from(ident
.clone()),
2131 colon_token
: colon_token
,
2137 #[cfg(feature = "full")]
2138 fn expr_struct_helper(
2140 outer_attrs
: Vec
<Attribute
>,
2142 ) -> Result
<ExprStruct
> {
2144 let brace_token
= braced
!(content
in input
);
2145 let inner_attrs
= content
.call(Attribute
::parse_inner
)?
;
2147 let mut fields
= Punctuated
::new();
2149 let attrs
= content
.call(Attribute
::parse_outer
)?
;
2150 if content
.fork().parse
::<Member
>().is_err() {
2151 if attrs
.is_empty() {
2154 return Err(content
.error("expected struct field"));
2158 fields
.push(FieldValue
{
2163 if !content
.peek(Token
![,]) {
2166 let punct
: Token
![,] = content
.parse()?
;
2167 fields
.push_punct(punct
);
2170 let (dot2_token
, rest
) = if fields
.empty_or_trailing() && content
.peek(Token
![..]) {
2171 let dot2_token
: Token
![..] = content
.parse()?
;
2172 let rest
: Expr
= content
.parse()?
;
2173 (Some(dot2_token
), Some(Box
::new(rest
)))
2179 attrs
: private
::attrs(outer_attrs
, inner_attrs
),
2180 brace_token
: brace_token
,
2183 dot2_token
: dot2_token
,
2188 #[cfg(feature = "full")]
2189 fn expr_unsafe(input
: ParseStream
) -> Result
<ExprUnsafe
> {
2190 let unsafe_token
: Token
![unsafe] = input
.parse()?
;
2193 let brace_token
= braced
!(content
in input
);
2194 let inner_attrs
= content
.call(Attribute
::parse_inner
)?
;
2195 let stmts
= content
.call(Block
::parse_within
)?
;
2199 unsafe_token
: unsafe_token
,
2201 brace_token
: brace_token
,
2207 #[cfg(feature = "full")]
2208 pub fn expr_block(input
: ParseStream
) -> Result
<ExprBlock
> {
2209 let label
: Option
<Label
> = input
.parse()?
;
2212 let brace_token
= braced
!(content
in input
);
2213 let inner_attrs
= content
.call(Attribute
::parse_inner
)?
;
2214 let stmts
= content
.call(Block
::parse_within
)?
;
2220 brace_token
: brace_token
,
2226 #[cfg(feature = "full")]
2227 fn expr_range(input
: ParseStream
, allow_struct
: AllowStruct
) -> Result
<ExprRange
> {
2231 limits
: input
.parse()?
,
2234 || input
.peek(Token
![,])
2235 || input
.peek(Token
![;])
2236 || !allow_struct
.0 && input
.peek(token
::Brace
)
2240 let to
= ambiguous_expr(input
, allow_struct
)?
;
2247 #[cfg(feature = "full")]
2248 impl Parse
for RangeLimits
{
2249 fn parse(input
: ParseStream
) -> Result
<Self> {
2250 let lookahead
= input
.lookahead1();
2251 if lookahead
.peek(Token
![..=]) {
2252 input
.parse().map(RangeLimits
::Closed
)
2253 } else if lookahead
.peek(Token
![...]) {
2254 let dot3
: Token
![...] = input
.parse()?
;
2255 Ok(RangeLimits
::Closed(Token
![..=](dot3
.spans
)))
2256 } else if lookahead
.peek(Token
![..]) {
2257 input
.parse().map(RangeLimits
::HalfOpen
)
2259 Err(lookahead
.error())
2264 impl Parse
for ExprPath
{
2265 fn parse(input
: ParseStream
) -> Result
<Self> {
2266 #[cfg(not(feature = "full"))]
2267 let attrs
= Vec
::new();
2268 #[cfg(feature = "full")]
2269 let attrs
= input
.call(Attribute
::parse_outer
)?
;
2271 let (qself
, path
) = path
::parsing
::qpath(input
, true)?
;
2281 #[cfg(feature = "full")]
2282 impl Parse
for Block
{
2283 fn parse(input
: ParseStream
) -> Result
<Self> {
2286 brace_token
: braced
!(content
in input
),
2287 stmts
: content
.call(Block
::parse_within
)?
,
2292 #[cfg(feature = "full")]
2294 /// Parse the body of a block as zero or more statements, possibly
2295 /// including one trailing expression.
2297 /// *This function is available if Syn is built with the `"parsing"`
2304 /// extern crate syn;
2306 /// use syn::{token, Attribute, Block, Ident, Result, Stmt};
2307 /// use syn::parse::{Parse, ParseStream};
2309 /// // Parse a function with no generics or parameter list.
2311 /// // fn playground {
2312 /// // let mut x = 1;
2314 /// // println!("{}", x);
2316 /// struct MiniFunction {
2317 /// attrs: Vec<Attribute>,
2318 /// fn_token: Token![fn],
2320 /// brace_token: token::Brace,
2321 /// stmts: Vec<Stmt>,
2324 /// impl Parse for MiniFunction {
2325 /// fn parse(input: ParseStream) -> Result<Self> {
2326 /// let outer_attrs = input.call(Attribute::parse_outer)?;
2327 /// let fn_token: Token![fn] = input.parse()?;
2328 /// let name: Ident = input.parse()?;
2331 /// let brace_token = braced!(content in input);
2332 /// let inner_attrs = content.call(Attribute::parse_inner)?;
2333 /// let stmts = content.call(Block::parse_within)?;
2335 /// Ok(MiniFunction {
2337 /// let mut attrs = outer_attrs;
2338 /// attrs.extend(inner_attrs);
2341 /// fn_token: fn_token,
2343 /// brace_token: brace_token,
2351 pub fn parse_within(input
: ParseStream
) -> Result
<Vec
<Stmt
>> {
2352 let mut stmts
= Vec
::new();
2354 while input
.peek(Token
![;]) {
2355 input
.parse
::<Token
![;]>()?
;
2357 if input
.is_empty() {
2360 let s
= parse_stmt(input
, true)?
;
2361 let requires_semicolon
= if let Stmt
::Expr(ref s
) = s
{
2362 requires_terminator(s
)
2367 if input
.is_empty() {
2369 } else if requires_semicolon
{
2370 return Err(input
.error("unexpected token"));
2377 #[cfg(feature = "full")]
2378 impl Parse
for Stmt
{
2379 fn parse(input
: ParseStream
) -> Result
<Self> {
2380 parse_stmt(input
, false)
2384 #[cfg(feature = "full")]
2385 fn parse_stmt(input
: ParseStream
, allow_nosemi
: bool
) -> Result
<Stmt
> {
2386 let ahead
= input
.fork();
2387 ahead
.call(Attribute
::parse_outer
)?
;
2390 let ahead
= ahead
.fork();
2391 // Only parse braces here; paren and bracket will get parsed as
2392 // expression statements
2393 ahead
.call(Path
::parse_mod_style
).is_ok()
2394 && ahead
.parse
::<Token
![!]>().is_ok()
2395 && (ahead
.peek(token
::Brace
) || ahead
.peek(Ident
))
2398 } else if ahead
.peek(Token
![let]) {
2399 stmt_local(input
).map(Stmt
::Local
)
2400 } else if ahead
.peek(Token
![pub])
2401 || ahead
.peek(Token
![crate]) && !ahead
.peek2(Token
![::])
2402 || ahead
.peek(Token
![extern]) && !ahead
.peek2(Token
![::])
2403 || ahead
.peek(Token
![use])
2404 || ahead
.peek(Token
![static]) && (ahead
.peek2(Token
![mut]) || ahead
.peek2(Ident
))
2405 || ahead
.peek(Token
![const])
2406 || ahead
.peek(Token
![unsafe]) && !ahead
.peek2(token
::Brace
)
2407 || ahead
.peek(Token
![async
]) && (ahead
.peek2(Token
![extern]) || ahead
.peek2(Token
![fn]))
2408 || ahead
.peek(Token
![fn])
2409 || ahead
.peek(Token
![mod])
2410 || ahead
.peek(Token
![type])
2411 || ahead
.peek(Token
![existential
]) && ahead
.peek2(Token
![type])
2412 || ahead
.peek(Token
![struct])
2413 || ahead
.peek(Token
![enum])
2414 || ahead
.peek(Token
![union]) && ahead
.peek2(Ident
)
2415 || ahead
.peek(Token
![auto]) && ahead
.peek2(Token
![trait])
2416 || ahead
.peek(Token
![trait])
2417 || ahead
.peek(Token
![default])
2418 && (ahead
.peek2(Token
![unsafe]) || ahead
.peek2(Token
![impl ]))
2419 || ahead
.peek(Token
![impl ])
2420 || ahead
.peek(Token
![macro])
2422 input
.parse().map(Stmt
::Item
)
2424 stmt_expr(input
, allow_nosemi
)
2428 #[cfg(feature = "full")]
2429 fn stmt_mac(input
: ParseStream
) -> Result
<Stmt
> {
2430 let attrs
= input
.call(Attribute
::parse_outer
)?
;
2431 let path
= input
.call(Path
::parse_mod_style
)?
;
2432 let bang_token
: Token
![!] = input
.parse()?
;
2433 let ident
: Option
<Ident
> = input
.parse()?
;
2434 let (delimiter
, tts
) = mac
::parse_delimiter(input
)?
;
2435 let semi_token
: Option
<Token
![;]> = input
.parse()?
;
2437 Ok(Stmt
::Item(Item
::Macro(ItemMacro
{
2442 bang_token
: bang_token
,
2443 delimiter
: delimiter
,
2446 semi_token
: semi_token
,
2450 #[cfg(feature = "full")]
2451 fn stmt_local(input
: ParseStream
) -> Result
<Local
> {
2453 attrs
: input
.call(Attribute
::parse_outer
)?
,
2454 let_token
: input
.parse()?
,
2456 let mut pats
= Punctuated
::new();
2457 let value
: Pat
= input
.parse()?
;
2458 pats
.push_value(value
);
2459 while input
.peek(Token
![|]) && !input
.peek(Token
![||]) && !input
.peek(Token
![|=]) {
2460 let punct
= input
.parse()?
;
2461 pats
.push_punct(punct
);
2462 let value
: Pat
= input
.parse()?
;
2463 pats
.push_value(value
);
2468 if input
.peek(Token
![:]) {
2469 let colon_token
: Token
![:] = input
.parse()?
;
2470 let ty
: Type
= input
.parse()?
;
2471 Some((colon_token
, Box
::new(ty
)))
2477 if input
.peek(Token
![=]) {
2478 let eq_token
: Token
![=] = input
.parse()?
;
2479 let init
: Expr
= input
.parse()?
;
2480 Some((eq_token
, Box
::new(init
)))
2485 semi_token
: input
.parse()?
,
2489 #[cfg(feature = "full")]
2490 fn stmt_expr(input
: ParseStream
, allow_nosemi
: bool
) -> Result
<Stmt
> {
2491 let mut attrs
= input
.call(Attribute
::parse_outer
)?
;
2492 let mut e
= expr_early(input
)?
;
2494 attrs
.extend(e
.replace_attrs(Vec
::new()));
2495 e
.replace_attrs(attrs
);
2497 if input
.peek(Token
![;]) {
2498 return Ok(Stmt
::Semi(e
, input
.parse()?
));
2501 if allow_nosemi
|| !requires_terminator(&e
) {
2504 Err(input
.error("expected semicolon"))
2508 #[cfg(feature = "full")]
2509 impl Parse
for Pat
{
2510 fn parse(input
: ParseStream
) -> Result
<Self> {
2511 let lookahead
= input
.lookahead1();
2512 if lookahead
.peek(Token
![_
]) {
2513 input
.call(pat_wild
).map(Pat
::Wild
)
2514 } else if lookahead
.peek(Token
![box]) {
2515 input
.call(pat_box
).map(Pat
::Box
)
2516 } else if lookahead
.peek(Token
![-]) || lookahead
.peek(Lit
) {
2517 pat_lit_or_range(input
)
2518 } else if input
.peek(Ident
)
2520 input
.peek2(Token
![::])
2521 || input
.peek2(Token
![!])
2522 || input
.peek2(token
::Brace
)
2523 || input
.peek2(token
::Paren
)
2524 || input
.peek2(Token
![..])
2526 let ahead
= input
.fork();
2527 ahead
.parse
::<Ident
>()?
;
2528 ahead
.parse
::<RangeLimits
>()?
;
2529 ahead
.is_empty() || ahead
.peek(Token
![,])
2532 || input
.peek(Token
![self]) && input
.peek2(Token
![::])
2533 || input
.peek(Token
![::])
2534 || input
.peek(Token
![<])
2535 || input
.peek(Token
![Self])
2536 || input
.peek(Token
![super])
2537 || input
.peek(Token
![extern])
2538 || input
.peek(Token
![crate])
2540 pat_path_or_macro_or_struct_or_range(input
)
2541 } else if input
.peek(Token
![ref])
2542 || input
.peek(Token
![mut])
2543 || input
.peek(Token
![self])
2544 || input
.peek(Ident
)
2546 input
.call(pat_ident
).map(Pat
::Ident
)
2547 } else if lookahead
.peek(token
::Paren
) {
2548 input
.call(pat_tuple
).map(Pat
::Tuple
)
2549 } else if lookahead
.peek(Token
![&]) {
2550 input
.call(pat_ref
).map(Pat
::Ref
)
2551 } else if lookahead
.peek(token
::Bracket
) {
2552 input
.call(pat_slice
).map(Pat
::Slice
)
2554 Err(lookahead
.error())
2559 #[cfg(feature = "full")]
2560 fn pat_path_or_macro_or_struct_or_range(input
: ParseStream
) -> Result
<Pat
> {
2561 let (qself
, path
) = path
::parsing
::qpath(input
, true)?
;
2563 if input
.peek(Token
![..]) {
2564 return pat_range(input
, qself
, path
).map(Pat
::Range
);
2567 if qself
.is_some() {
2568 return Ok(Pat
::Path(PatPath
{
2574 if input
.peek(Token
![!]) && !input
.peek(Token
![!=]) {
2575 let mut contains_arguments
= false;
2576 for segment
in &path
.segments
{
2577 match segment
.arguments
{
2578 PathArguments
::None
=> {}
2579 PathArguments
::AngleBracketed(_
) | PathArguments
::Parenthesized(_
) => {
2580 contains_arguments
= true;
2585 if !contains_arguments
{
2586 let bang_token
: Token
![!] = input
.parse()?
;
2587 let (delimiter
, tts
) = mac
::parse_delimiter(input
)?
;
2588 return Ok(Pat
::Macro(PatMacro
{
2591 bang_token
: bang_token
,
2592 delimiter
: delimiter
,
2599 if input
.peek(token
::Brace
) {
2600 pat_struct(input
, path
).map(Pat
::Struct
)
2601 } else if input
.peek(token
::Paren
) {
2602 pat_tuple_struct(input
, path
).map(Pat
::TupleStruct
)
2603 } else if input
.peek(Token
![..]) {
2604 pat_range(input
, qself
, path
).map(Pat
::Range
)
2606 Ok(Pat
::Path(PatPath
{
2613 #[cfg(feature = "full")]
2614 fn pat_wild(input
: ParseStream
) -> Result
<PatWild
> {
2616 underscore_token
: input
.parse()?
,
2620 #[cfg(feature = "full")]
2621 fn pat_box(input
: ParseStream
) -> Result
<PatBox
> {
2623 box_token
: input
.parse()?
,
2624 pat
: input
.parse()?
,
2628 #[cfg(feature = "full")]
2629 fn pat_ident(input
: ParseStream
) -> Result
<PatIdent
> {
2631 by_ref
: input
.parse()?
,
2632 mutability
: input
.parse()?
,
2633 ident
: input
.call(Ident
::parse_any
)?
,
2635 if input
.peek(Token
![@
]) {
2636 let at_token
: Token
![@
] = input
.parse()?
;
2637 let subpat
: Pat
= input
.parse()?
;
2638 Some((at_token
, Box
::new(subpat
)))
2646 #[cfg(feature = "full")]
2647 fn pat_tuple_struct(input
: ParseStream
, path
: Path
) -> Result
<PatTupleStruct
> {
2650 pat
: input
.call(pat_tuple
)?
,
2654 #[cfg(feature = "full")]
2655 fn pat_struct(input
: ParseStream
, path
: Path
) -> Result
<PatStruct
> {
2657 let brace_token
= braced
!(content
in input
);
2659 let mut fields
= Punctuated
::new();
2660 while !content
.is_empty() && !content
.peek(Token
![..]) {
2661 let value
= content
.call(field_pat
)?
;
2662 fields
.push_value(value
);
2663 if !content
.peek(Token
![,]) {
2666 let punct
: Token
![,] = content
.parse()?
;
2667 fields
.push_punct(punct
);
2670 let dot2_token
= if fields
.empty_or_trailing() && content
.peek(Token
![..]) {
2671 Some(content
.parse()?
)
2678 brace_token
: brace_token
,
2680 dot2_token
: dot2_token
,
2684 #[cfg(feature = "full")]
2685 fn field_pat(input
: ParseStream
) -> Result
<FieldPat
> {
2686 let boxed
: Option
<Token
![box]> = input
.parse()?
;
2687 let by_ref
: Option
<Token
![ref]> = input
.parse()?
;
2688 let mutability
: Option
<Token
![mut]> = input
.parse()?
;
2689 let member
: Member
= input
.parse()?
;
2691 if boxed
.is_none() && by_ref
.is_none() && mutability
.is_none() && input
.peek(Token
![:])
2692 || member
.is_unnamed()
2694 return Ok(FieldPat
{
2697 colon_token
: input
.parse()?
,
2698 pat
: input
.parse()?
,
2702 let ident
= match member
{
2703 Member
::Named(ident
) => ident
,
2704 Member
::Unnamed(_
) => unreachable
!(),
2707 let mut pat
= Pat
::Ident(PatIdent
{
2709 mutability
: mutability
,
2710 ident
: ident
.clone(),
2714 if let Some(boxed
) = boxed
{
2715 pat
= Pat
::Box(PatBox
{
2722 member
: Member
::Named(ident
),
2729 impl Parse
for Member
{
2730 fn parse(input
: ParseStream
) -> Result
<Self> {
2731 if input
.peek(Ident
) {
2732 input
.parse().map(Member
::Named
)
2733 } else if input
.peek(LitInt
) {
2734 input
.parse().map(Member
::Unnamed
)
2736 Err(input
.error("expected identifier or integer"))
2741 #[cfg(feature = "full")]
2742 impl Parse
for Arm
{
2743 fn parse(input
: ParseStream
) -> Result
<Arm
> {
2746 attrs
: input
.call(Attribute
::parse_outer
)?
,
2747 leading_vert
: input
.parse()?
,
2749 let mut pats
= Punctuated
::new();
2750 let value
: Pat
= input
.parse()?
;
2751 pats
.push_value(value
);
2753 if !input
.peek(Token
![|]) {
2756 let punct
= input
.parse()?
;
2757 pats
.push_punct(punct
);
2758 let value
: Pat
= input
.parse()?
;
2759 pats
.push_value(value
);
2764 if input
.peek(Token
![if]) {
2765 let if_token
: Token
![if] = input
.parse()?
;
2766 let guard
: Expr
= input
.parse()?
;
2767 Some((if_token
, Box
::new(guard
)))
2772 fat_arrow_token
: input
.parse()?
,
2774 let body
= input
.call(expr_early
)?
;
2775 requires_comma
= requires_terminator(&body
);
2779 if requires_comma
&& !input
.is_empty() {
2780 Some(input
.parse()?
)
2789 impl Parse
for Index
{
2790 fn parse(input
: ParseStream
) -> Result
<Self> {
2791 let lit
: LitInt
= input
.parse()?
;
2792 if let IntSuffix
::None
= lit
.suffix() {
2794 index
: lit
.value() as u32,
2798 Err(Error
::new(lit
.span(), "expected unsuffixed integer"))
2803 #[cfg(feature = "full")]
2804 fn pat_range(input
: ParseStream
, qself
: Option
<QSelf
>, path
: Path
) -> Result
<PatRange
> {
2806 lo
: Box
::new(Expr
::Path(ExprPath
{
2811 limits
: input
.parse()?
,
2812 hi
: input
.call(pat_lit_expr
)?
,
2816 #[cfg(feature = "full")]
2817 fn pat_tuple(input
: ParseStream
) -> Result
<PatTuple
> {
2819 let paren_token
= parenthesized
!(content
in input
);
2821 let mut front
= Punctuated
::new();
2822 let mut dot2_token
= None
::<Token
![..]>;
2823 let mut comma_token
= None
::<Token
![,]>;
2825 if content
.is_empty() {
2828 if content
.peek(Token
![..]) {
2829 dot2_token
= Some(content
.parse()?
);
2830 comma_token
= content
.parse()?
;
2833 let value
: Pat
= content
.parse()?
;
2834 front
.push_value(value
);
2835 if content
.is_empty() {
2838 let punct
= content
.parse()?
;
2839 front
.push_punct(punct
);
2842 let mut back
= Punctuated
::new();
2843 while !content
.is_empty() {
2844 let value
: Pat
= content
.parse()?
;
2845 back
.push_value(value
);
2846 if content
.is_empty() {
2849 let punct
= content
.parse()?
;
2850 back
.push_punct(punct
);
2854 paren_token
: paren_token
,
2856 dot2_token
: dot2_token
,
2857 comma_token
: comma_token
,
2862 #[cfg(feature = "full")]
2863 fn pat_ref(input
: ParseStream
) -> Result
<PatRef
> {
2865 and_token
: input
.parse()?
,
2866 mutability
: input
.parse()?
,
2867 pat
: input
.parse()?
,
2871 #[cfg(feature = "full")]
2872 fn pat_lit_or_range(input
: ParseStream
) -> Result
<Pat
> {
2873 let lo
= input
.call(pat_lit_expr
)?
;
2874 if input
.peek(Token
![..]) {
2875 Ok(Pat
::Range(PatRange
{
2877 limits
: input
.parse()?
,
2878 hi
: input
.call(pat_lit_expr
)?
,
2881 Ok(Pat
::Lit(PatLit { expr: lo }
))
2885 #[cfg(feature = "full")]
2886 fn pat_lit_expr(input
: ParseStream
) -> Result
<Box
<Expr
>> {
2887 let neg
: Option
<Token
![-]> = input
.parse()?
;
2889 let lookahead
= input
.lookahead1();
2890 let expr
= if lookahead
.peek(Lit
) {
2891 Expr
::Lit(input
.call(expr_lit
)?
)
2892 } else if lookahead
.peek(Ident
)
2893 || lookahead
.peek(Token
![::])
2894 || lookahead
.peek(Token
![<])
2895 || lookahead
.peek(Token
![self])
2896 || lookahead
.peek(Token
![Self])
2897 || lookahead
.peek(Token
![super])
2898 || lookahead
.peek(Token
![extern])
2899 || lookahead
.peek(Token
![crate])
2901 Expr
::Path(input
.parse()?
)
2903 return Err(lookahead
.error());
2906 Ok(Box
::new(if let Some(neg
) = neg
{
2907 Expr
::Unary(ExprUnary
{
2910 expr
: Box
::new(expr
),
2917 #[cfg(feature = "full")]
2918 fn pat_slice(input
: ParseStream
) -> Result
<PatSlice
> {
2920 let bracket_token
= bracketed
!(content
in input
);
2922 let mut front
= Punctuated
::new();
2923 let mut middle
= None
;
2925 if content
.is_empty() || content
.peek(Token
![..]) {
2928 let value
: Pat
= content
.parse()?
;
2929 if content
.peek(Token
![..]) {
2930 middle
= Some(Box
::new(value
));
2933 front
.push_value(value
);
2934 if content
.is_empty() {
2937 let punct
= content
.parse()?
;
2938 front
.push_punct(punct
);
2941 let dot2_token
: Option
<Token
![..]> = content
.parse()?
;
2942 let mut comma_token
= None
::<Token
![,]>;
2943 let mut back
= Punctuated
::new();
2944 if dot2_token
.is_some() {
2945 comma_token
= content
.parse()?
;
2946 if comma_token
.is_some() {
2948 if content
.is_empty() {
2951 let value
: Pat
= content
.parse()?
;
2952 back
.push_value(value
);
2953 if content
.is_empty() {
2956 let punct
= content
.parse()?
;
2957 back
.push_punct(punct
);
2963 bracket_token
: bracket_token
,
2966 dot2_token
: dot2_token
,
2967 comma_token
: comma_token
,
2972 #[cfg(feature = "full")]
2974 fn is_named(&self) -> bool
{
2976 Member
::Named(_
) => true,
2977 Member
::Unnamed(_
) => false,
2981 fn is_unnamed(&self) -> bool
{
2983 Member
::Named(_
) => false,
2984 Member
::Unnamed(_
) => true,
2990 #[cfg(feature = "printing")]
2994 use proc_macro2
::{Literal, TokenStream}
;
2995 use quote
::{ToTokens, TokenStreamExt}
;
2997 #[cfg(feature = "full")]
2998 use attr
::FilterAttrs
;
2999 #[cfg(feature = "full")]
3000 use print
::TokensOrDefault
;
3002 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
3003 // before appending it to `TokenStream`.
3004 #[cfg(feature = "full")]
3005 fn wrap_bare_struct(tokens
: &mut TokenStream
, e
: &Expr
) {
3006 if let Expr
::Struct(_
) = *e
{
3007 token
::Paren
::default().surround(tokens
, |tokens
| {
3008 e
.to_tokens(tokens
);
3011 e
.to_tokens(tokens
);
3015 #[cfg(feature = "full")]
3016 fn outer_attrs_to_tokens(attrs
: &[Attribute
], tokens
: &mut TokenStream
) {
3017 tokens
.append_all(attrs
.outer());
3020 #[cfg(feature = "full")]
3021 fn inner_attrs_to_tokens(attrs
: &[Attribute
], tokens
: &mut TokenStream
) {
3022 tokens
.append_all(attrs
.inner());
3025 #[cfg(not(feature = "full"))]
3026 fn outer_attrs_to_tokens(_attrs
: &[Attribute
], _tokens
: &mut TokenStream
) {}
3028 #[cfg(not(feature = "full"))]
3029 fn inner_attrs_to_tokens(_attrs
: &[Attribute
], _tokens
: &mut TokenStream
) {}
3031 #[cfg(feature = "full")]
3032 impl ToTokens
for ExprBox
{
3033 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3034 outer_attrs_to_tokens(&self.attrs
, tokens
);
3035 self.box_token
.to_tokens(tokens
);
3036 self.expr
.to_tokens(tokens
);
3040 #[cfg(feature = "full")]
3041 impl ToTokens
for ExprInPlace
{
3042 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3043 outer_attrs_to_tokens(&self.attrs
, tokens
);
3044 self.place
.to_tokens(tokens
);
3045 self.arrow_token
.to_tokens(tokens
);
3046 self.value
.to_tokens(tokens
);
3050 #[cfg(feature = "full")]
3051 impl ToTokens
for ExprArray
{
3052 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3053 outer_attrs_to_tokens(&self.attrs
, tokens
);
3054 self.bracket_token
.surround(tokens
, |tokens
| {
3055 inner_attrs_to_tokens(&self.attrs
, tokens
);
3056 self.elems
.to_tokens(tokens
);
3061 impl ToTokens
for ExprCall
{
3062 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3063 outer_attrs_to_tokens(&self.attrs
, tokens
);
3064 self.func
.to_tokens(tokens
);
3065 self.paren_token
.surround(tokens
, |tokens
| {
3066 self.args
.to_tokens(tokens
);
3071 #[cfg(feature = "full")]
3072 impl ToTokens
for ExprMethodCall
{
3073 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3074 outer_attrs_to_tokens(&self.attrs
, tokens
);
3075 self.receiver
.to_tokens(tokens
);
3076 self.dot_token
.to_tokens(tokens
);
3077 self.method
.to_tokens(tokens
);
3078 self.turbofish
.to_tokens(tokens
);
3079 self.paren_token
.surround(tokens
, |tokens
| {
3080 self.args
.to_tokens(tokens
);
3085 #[cfg(feature = "full")]
3086 impl ToTokens
for MethodTurbofish
{
3087 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3088 self.colon2_token
.to_tokens(tokens
);
3089 self.lt_token
.to_tokens(tokens
);
3090 self.args
.to_tokens(tokens
);
3091 self.gt_token
.to_tokens(tokens
);
3095 #[cfg(feature = "full")]
3096 impl ToTokens
for GenericMethodArgument
{
3097 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3099 GenericMethodArgument
::Type(ref t
) => t
.to_tokens(tokens
),
3100 GenericMethodArgument
::Const(ref c
) => c
.to_tokens(tokens
),
3105 #[cfg(feature = "full")]
3106 impl ToTokens
for ExprTuple
{
3107 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3108 outer_attrs_to_tokens(&self.attrs
, tokens
);
3109 self.paren_token
.surround(tokens
, |tokens
| {
3110 inner_attrs_to_tokens(&self.attrs
, tokens
);
3111 self.elems
.to_tokens(tokens
);
3112 // If we only have one argument, we need a trailing comma to
3113 // distinguish ExprTuple from ExprParen.
3114 if self.elems
.len() == 1 && !self.elems
.trailing_punct() {
3115 <Token
![,]>::default().to_tokens(tokens
);
3121 impl ToTokens
for ExprBinary
{
3122 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3123 outer_attrs_to_tokens(&self.attrs
, tokens
);
3124 self.left
.to_tokens(tokens
);
3125 self.op
.to_tokens(tokens
);
3126 self.right
.to_tokens(tokens
);
3130 impl ToTokens
for ExprUnary
{
3131 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3132 outer_attrs_to_tokens(&self.attrs
, tokens
);
3133 self.op
.to_tokens(tokens
);
3134 self.expr
.to_tokens(tokens
);
3138 impl ToTokens
for ExprLit
{
3139 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3140 outer_attrs_to_tokens(&self.attrs
, tokens
);
3141 self.lit
.to_tokens(tokens
);
3145 impl ToTokens
for ExprCast
{
3146 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3147 outer_attrs_to_tokens(&self.attrs
, tokens
);
3148 self.expr
.to_tokens(tokens
);
3149 self.as_token
.to_tokens(tokens
);
3150 self.ty
.to_tokens(tokens
);
3154 #[cfg(feature = "full")]
3155 impl ToTokens
for ExprType
{
3156 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3157 outer_attrs_to_tokens(&self.attrs
, tokens
);
3158 self.expr
.to_tokens(tokens
);
3159 self.colon_token
.to_tokens(tokens
);
3160 self.ty
.to_tokens(tokens
);
3164 #[cfg(feature = "full")]
3165 fn maybe_wrap_else(tokens
: &mut TokenStream
, else_
: &Option
<(Token
![else], Box
<Expr
>)>) {
3166 if let Some((ref else_token
, ref else_
)) = *else_
{
3167 else_token
.to_tokens(tokens
);
3169 // If we are not one of the valid expressions to exist in an else
3170 // clause, wrap ourselves in a block.
3172 Expr
::If(_
) | Expr
::Block(_
) => {
3173 else_
.to_tokens(tokens
);
3176 token
::Brace
::default().surround(tokens
, |tokens
| {
3177 else_
.to_tokens(tokens
);
3184 #[cfg(feature = "full")]
3185 impl ToTokens
for ExprLet
{
3186 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3187 outer_attrs_to_tokens(&self.attrs
, tokens
);
3188 self.let_token
.to_tokens(tokens
);
3189 self.pats
.to_tokens(tokens
);
3190 self.eq_token
.to_tokens(tokens
);
3191 wrap_bare_struct(tokens
, &self.expr
);
3195 #[cfg(feature = "full")]
3196 impl ToTokens
for ExprIf
{
3197 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3198 outer_attrs_to_tokens(&self.attrs
, tokens
);
3199 self.if_token
.to_tokens(tokens
);
3200 wrap_bare_struct(tokens
, &self.cond
);
3201 self.then_branch
.to_tokens(tokens
);
3202 maybe_wrap_else(tokens
, &self.else_branch
);
3206 #[cfg(feature = "full")]
3207 impl ToTokens
for ExprWhile
{
3208 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3209 outer_attrs_to_tokens(&self.attrs
, tokens
);
3210 self.label
.to_tokens(tokens
);
3211 self.while_token
.to_tokens(tokens
);
3212 wrap_bare_struct(tokens
, &self.cond
);
3213 self.body
.brace_token
.surround(tokens
, |tokens
| {
3214 inner_attrs_to_tokens(&self.attrs
, tokens
);
3215 tokens
.append_all(&self.body
.stmts
);
3220 #[cfg(feature = "full")]
3221 impl ToTokens
for ExprForLoop
{
3222 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3223 outer_attrs_to_tokens(&self.attrs
, tokens
);
3224 self.label
.to_tokens(tokens
);
3225 self.for_token
.to_tokens(tokens
);
3226 self.pat
.to_tokens(tokens
);
3227 self.in_token
.to_tokens(tokens
);
3228 wrap_bare_struct(tokens
, &self.expr
);
3229 self.body
.brace_token
.surround(tokens
, |tokens
| {
3230 inner_attrs_to_tokens(&self.attrs
, tokens
);
3231 tokens
.append_all(&self.body
.stmts
);
3236 #[cfg(feature = "full")]
3237 impl ToTokens
for ExprLoop
{
3238 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3239 outer_attrs_to_tokens(&self.attrs
, tokens
);
3240 self.label
.to_tokens(tokens
);
3241 self.loop_token
.to_tokens(tokens
);
3242 self.body
.brace_token
.surround(tokens
, |tokens
| {
3243 inner_attrs_to_tokens(&self.attrs
, tokens
);
3244 tokens
.append_all(&self.body
.stmts
);
3249 #[cfg(feature = "full")]
3250 impl ToTokens
for ExprMatch
{
3251 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3252 outer_attrs_to_tokens(&self.attrs
, tokens
);
3253 self.match_token
.to_tokens(tokens
);
3254 wrap_bare_struct(tokens
, &self.expr
);
3255 self.brace_token
.surround(tokens
, |tokens
| {
3256 inner_attrs_to_tokens(&self.attrs
, tokens
);
3257 for (i
, arm
) in self.arms
.iter().enumerate() {
3258 arm
.to_tokens(tokens
);
3259 // Ensure that we have a comma after a non-block arm, except
3260 // for the last one.
3261 let is_last
= i
== self.arms
.len() - 1;
3262 if !is_last
&& requires_terminator(&arm
.body
) && arm
.comma
.is_none() {
3263 <Token
![,]>::default().to_tokens(tokens
);
3270 #[cfg(feature = "full")]
3271 impl ToTokens
for ExprAsync
{
3272 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3273 outer_attrs_to_tokens(&self.attrs
, tokens
);
3274 self.async_token
.to_tokens(tokens
);
3275 self.capture
.to_tokens(tokens
);
3276 self.block
.to_tokens(tokens
);
3280 #[cfg(feature = "full")]
3281 impl ToTokens
for ExprTryBlock
{
3282 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3283 outer_attrs_to_tokens(&self.attrs
, tokens
);
3284 self.try_token
.to_tokens(tokens
);
3285 self.block
.to_tokens(tokens
);
3289 #[cfg(feature = "full")]
3290 impl ToTokens
for ExprYield
{
3291 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3292 outer_attrs_to_tokens(&self.attrs
, tokens
);
3293 self.yield_token
.to_tokens(tokens
);
3294 self.expr
.to_tokens(tokens
);
3298 #[cfg(feature = "full")]
3299 impl ToTokens
for ExprClosure
{
3300 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3301 outer_attrs_to_tokens(&self.attrs
, tokens
);
3302 self.asyncness
.to_tokens(tokens
);
3303 self.movability
.to_tokens(tokens
);
3304 self.capture
.to_tokens(tokens
);
3305 self.or1_token
.to_tokens(tokens
);
3306 for input
in self.inputs
.pairs() {
3307 match **input
.value() {
3308 FnArg
::Captured(ArgCaptured
{
3313 pat
.to_tokens(tokens
);
3315 _
=> input
.value().to_tokens(tokens
),
3317 input
.punct().to_tokens(tokens
);
3319 self.or2_token
.to_tokens(tokens
);
3320 self.output
.to_tokens(tokens
);
3321 self.body
.to_tokens(tokens
);
3325 #[cfg(feature = "full")]
3326 impl ToTokens
for ExprUnsafe
{
3327 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3328 outer_attrs_to_tokens(&self.attrs
, tokens
);
3329 self.unsafe_token
.to_tokens(tokens
);
3330 self.block
.brace_token
.surround(tokens
, |tokens
| {
3331 inner_attrs_to_tokens(&self.attrs
, tokens
);
3332 tokens
.append_all(&self.block
.stmts
);
3337 #[cfg(feature = "full")]
3338 impl ToTokens
for ExprBlock
{
3339 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3340 outer_attrs_to_tokens(&self.attrs
, tokens
);
3341 self.label
.to_tokens(tokens
);
3342 self.block
.brace_token
.surround(tokens
, |tokens
| {
3343 inner_attrs_to_tokens(&self.attrs
, tokens
);
3344 tokens
.append_all(&self.block
.stmts
);
3349 #[cfg(feature = "full")]
3350 impl ToTokens
for ExprAssign
{
3351 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3352 outer_attrs_to_tokens(&self.attrs
, tokens
);
3353 self.left
.to_tokens(tokens
);
3354 self.eq_token
.to_tokens(tokens
);
3355 self.right
.to_tokens(tokens
);
3359 #[cfg(feature = "full")]
3360 impl ToTokens
for ExprAssignOp
{
3361 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3362 outer_attrs_to_tokens(&self.attrs
, tokens
);
3363 self.left
.to_tokens(tokens
);
3364 self.op
.to_tokens(tokens
);
3365 self.right
.to_tokens(tokens
);
3369 impl ToTokens
for ExprField
{
3370 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3371 outer_attrs_to_tokens(&self.attrs
, tokens
);
3372 self.base
.to_tokens(tokens
);
3373 self.dot_token
.to_tokens(tokens
);
3374 self.member
.to_tokens(tokens
);
3378 impl ToTokens
for Member
{
3379 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3381 Member
::Named(ref ident
) => ident
.to_tokens(tokens
),
3382 Member
::Unnamed(ref index
) => index
.to_tokens(tokens
),
3387 impl ToTokens
for Index
{
3388 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3389 let mut lit
= Literal
::i64_unsuffixed(i64::from(self.index
));
3390 lit
.set_span(self.span
);
3395 impl ToTokens
for ExprIndex
{
3396 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3397 outer_attrs_to_tokens(&self.attrs
, tokens
);
3398 self.expr
.to_tokens(tokens
);
3399 self.bracket_token
.surround(tokens
, |tokens
| {
3400 self.index
.to_tokens(tokens
);
3405 #[cfg(feature = "full")]
3406 impl ToTokens
for ExprRange
{
3407 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3408 outer_attrs_to_tokens(&self.attrs
, tokens
);
3409 self.from
.to_tokens(tokens
);
3411 RangeLimits
::HalfOpen(ref t
) => t
.to_tokens(tokens
),
3412 RangeLimits
::Closed(ref t
) => t
.to_tokens(tokens
),
3414 self.to
.to_tokens(tokens
);
3418 impl ToTokens
for ExprPath
{
3419 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3420 outer_attrs_to_tokens(&self.attrs
, tokens
);
3421 private
::print_path(tokens
, &self.qself
, &self.path
);
3425 #[cfg(feature = "full")]
3426 impl ToTokens
for ExprReference
{
3427 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3428 outer_attrs_to_tokens(&self.attrs
, tokens
);
3429 self.and_token
.to_tokens(tokens
);
3430 self.mutability
.to_tokens(tokens
);
3431 self.expr
.to_tokens(tokens
);
3435 #[cfg(feature = "full")]
3436 impl ToTokens
for ExprBreak
{
3437 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3438 outer_attrs_to_tokens(&self.attrs
, tokens
);
3439 self.break_token
.to_tokens(tokens
);
3440 self.label
.to_tokens(tokens
);
3441 self.expr
.to_tokens(tokens
);
3445 #[cfg(feature = "full")]
3446 impl ToTokens
for ExprContinue
{
3447 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3448 outer_attrs_to_tokens(&self.attrs
, tokens
);
3449 self.continue_token
.to_tokens(tokens
);
3450 self.label
.to_tokens(tokens
);
3454 #[cfg(feature = "full")]
3455 impl ToTokens
for ExprReturn
{
3456 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3457 outer_attrs_to_tokens(&self.attrs
, tokens
);
3458 self.return_token
.to_tokens(tokens
);
3459 self.expr
.to_tokens(tokens
);
3463 #[cfg(feature = "full")]
3464 impl ToTokens
for ExprMacro
{
3465 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3466 outer_attrs_to_tokens(&self.attrs
, tokens
);
3467 self.mac
.to_tokens(tokens
);
3471 #[cfg(feature = "full")]
3472 impl ToTokens
for ExprStruct
{
3473 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3474 outer_attrs_to_tokens(&self.attrs
, tokens
);
3475 self.path
.to_tokens(tokens
);
3476 self.brace_token
.surround(tokens
, |tokens
| {
3477 inner_attrs_to_tokens(&self.attrs
, tokens
);
3478 self.fields
.to_tokens(tokens
);
3479 if self.rest
.is_some() {
3480 TokensOrDefault(&self.dot2_token
).to_tokens(tokens
);
3481 self.rest
.to_tokens(tokens
);
3487 #[cfg(feature = "full")]
3488 impl ToTokens
for ExprRepeat
{
3489 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3490 outer_attrs_to_tokens(&self.attrs
, tokens
);
3491 self.bracket_token
.surround(tokens
, |tokens
| {
3492 inner_attrs_to_tokens(&self.attrs
, tokens
);
3493 self.expr
.to_tokens(tokens
);
3494 self.semi_token
.to_tokens(tokens
);
3495 self.len
.to_tokens(tokens
);
3500 #[cfg(feature = "full")]
3501 impl ToTokens
for ExprGroup
{
3502 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3503 outer_attrs_to_tokens(&self.attrs
, tokens
);
3504 self.group_token
.surround(tokens
, |tokens
| {
3505 self.expr
.to_tokens(tokens
);
3510 impl ToTokens
for ExprParen
{
3511 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3512 outer_attrs_to_tokens(&self.attrs
, tokens
);
3513 self.paren_token
.surround(tokens
, |tokens
| {
3514 inner_attrs_to_tokens(&self.attrs
, tokens
);
3515 self.expr
.to_tokens(tokens
);
3520 #[cfg(feature = "full")]
3521 impl ToTokens
for ExprTry
{
3522 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3523 outer_attrs_to_tokens(&self.attrs
, tokens
);
3524 self.expr
.to_tokens(tokens
);
3525 self.question_token
.to_tokens(tokens
);
3529 impl ToTokens
for ExprVerbatim
{
3530 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3531 self.tts
.to_tokens(tokens
);
3535 #[cfg(feature = "full")]
3536 impl ToTokens
for Label
{
3537 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3538 self.name
.to_tokens(tokens
);
3539 self.colon_token
.to_tokens(tokens
);
3543 #[cfg(feature = "full")]
3544 impl ToTokens
for FieldValue
{
3545 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3546 outer_attrs_to_tokens(&self.attrs
, tokens
);
3547 self.member
.to_tokens(tokens
);
3548 if let Some(ref colon_token
) = self.colon_token
{
3549 colon_token
.to_tokens(tokens
);
3550 self.expr
.to_tokens(tokens
);
3555 #[cfg(feature = "full")]
3556 impl ToTokens
for Arm
{
3557 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3558 tokens
.append_all(&self.attrs
);
3559 self.leading_vert
.to_tokens(tokens
);
3560 self.pats
.to_tokens(tokens
);
3561 if let Some((ref if_token
, ref guard
)) = self.guard
{
3562 if_token
.to_tokens(tokens
);
3563 guard
.to_tokens(tokens
);
3565 self.fat_arrow_token
.to_tokens(tokens
);
3566 self.body
.to_tokens(tokens
);
3567 self.comma
.to_tokens(tokens
);
3571 #[cfg(feature = "full")]
3572 impl ToTokens
for PatWild
{
3573 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3574 self.underscore_token
.to_tokens(tokens
);
3578 #[cfg(feature = "full")]
3579 impl ToTokens
for PatIdent
{
3580 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3581 self.by_ref
.to_tokens(tokens
);
3582 self.mutability
.to_tokens(tokens
);
3583 self.ident
.to_tokens(tokens
);
3584 if let Some((ref at_token
, ref subpat
)) = self.subpat
{
3585 at_token
.to_tokens(tokens
);
3586 subpat
.to_tokens(tokens
);
3591 #[cfg(feature = "full")]
3592 impl ToTokens
for PatStruct
{
3593 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3594 self.path
.to_tokens(tokens
);
3595 self.brace_token
.surround(tokens
, |tokens
| {
3596 self.fields
.to_tokens(tokens
);
3597 // NOTE: We need a comma before the dot2 token if it is present.
3598 if !self.fields
.empty_or_trailing() && self.dot2_token
.is_some() {
3599 <Token
![,]>::default().to_tokens(tokens
);
3601 self.dot2_token
.to_tokens(tokens
);
3606 #[cfg(feature = "full")]
3607 impl ToTokens
for PatTupleStruct
{
3608 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3609 self.path
.to_tokens(tokens
);
3610 self.pat
.to_tokens(tokens
);
3614 #[cfg(feature = "full")]
3615 impl ToTokens
for PatPath
{
3616 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3617 private
::print_path(tokens
, &self.qself
, &self.path
);
3621 #[cfg(feature = "full")]
3622 impl ToTokens
for PatTuple
{
3623 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3624 self.paren_token
.surround(tokens
, |tokens
| {
3625 self.front
.to_tokens(tokens
);
3626 if let Some(ref dot2_token
) = self.dot2_token
{
3627 if !self.front
.empty_or_trailing() {
3628 // Ensure there is a comma before the .. token.
3629 <Token
![,]>::default().to_tokens(tokens
);
3631 dot2_token
.to_tokens(tokens
);
3632 self.comma_token
.to_tokens(tokens
);
3633 if self.comma_token
.is_none() && !self.back
.is_empty() {
3634 // Ensure there is a comma after the .. token.
3635 <Token
![,]>::default().to_tokens(tokens
);
3638 self.back
.to_tokens(tokens
);
3643 #[cfg(feature = "full")]
3644 impl ToTokens
for PatBox
{
3645 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3646 self.box_token
.to_tokens(tokens
);
3647 self.pat
.to_tokens(tokens
);
3651 #[cfg(feature = "full")]
3652 impl ToTokens
for PatRef
{
3653 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3654 self.and_token
.to_tokens(tokens
);
3655 self.mutability
.to_tokens(tokens
);
3656 self.pat
.to_tokens(tokens
);
3660 #[cfg(feature = "full")]
3661 impl ToTokens
for PatLit
{
3662 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3663 self.expr
.to_tokens(tokens
);
3667 #[cfg(feature = "full")]
3668 impl ToTokens
for PatRange
{
3669 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3670 self.lo
.to_tokens(tokens
);
3672 RangeLimits
::HalfOpen(ref t
) => t
.to_tokens(tokens
),
3673 RangeLimits
::Closed(ref t
) => Token
![...](t
.spans
).to_tokens(tokens
),
3675 self.hi
.to_tokens(tokens
);
3679 #[cfg(feature = "full")]
3680 impl ToTokens
for PatSlice
{
3681 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3682 self.bracket_token
.surround(tokens
, |tokens
| {
3683 self.front
.to_tokens(tokens
);
3685 // If we need a comma before the middle or standalone .. token,
3686 // then make sure it's present.
3687 if !self.front
.empty_or_trailing()
3688 && (self.middle
.is_some() || self.dot2_token
.is_some())
3690 <Token
![,]>::default().to_tokens(tokens
);
3693 // If we have an identifier, we always need a .. token.
3694 if self.middle
.is_some() {
3695 self.middle
.to_tokens(tokens
);
3696 TokensOrDefault(&self.dot2_token
).to_tokens(tokens
);
3697 } else if self.dot2_token
.is_some() {
3698 self.dot2_token
.to_tokens(tokens
);
3701 // Make sure we have a comma before the back half.
3702 if !self.back
.is_empty() {
3703 TokensOrDefault(&self.comma_token
).to_tokens(tokens
);
3704 self.back
.to_tokens(tokens
);
3706 self.comma_token
.to_tokens(tokens
);
3712 #[cfg(feature = "full")]
3713 impl ToTokens
for PatMacro
{
3714 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3715 self.mac
.to_tokens(tokens
);
3719 #[cfg(feature = "full")]
3720 impl ToTokens
for PatVerbatim
{
3721 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3722 self.tts
.to_tokens(tokens
);
3726 #[cfg(feature = "full")]
3727 impl ToTokens
for FieldPat
{
3728 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3729 if let Some(ref colon_token
) = self.colon_token
{
3730 self.member
.to_tokens(tokens
);
3731 colon_token
.to_tokens(tokens
);
3733 self.pat
.to_tokens(tokens
);
3737 #[cfg(feature = "full")]
3738 impl ToTokens
for Block
{
3739 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3740 self.brace_token
.surround(tokens
, |tokens
| {
3741 tokens
.append_all(&self.stmts
);
3746 #[cfg(feature = "full")]
3747 impl ToTokens
for Stmt
{
3748 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3750 Stmt
::Local(ref local
) => local
.to_tokens(tokens
),
3751 Stmt
::Item(ref item
) => item
.to_tokens(tokens
),
3752 Stmt
::Expr(ref expr
) => expr
.to_tokens(tokens
),
3753 Stmt
::Semi(ref expr
, ref semi
) => {
3754 expr
.to_tokens(tokens
);
3755 semi
.to_tokens(tokens
);
3761 #[cfg(feature = "full")]
3762 impl ToTokens
for Local
{
3763 fn to_tokens(&self, tokens
: &mut TokenStream
) {
3764 outer_attrs_to_tokens(&self.attrs
, tokens
);
3765 self.let_token
.to_tokens(tokens
);
3766 self.pats
.to_tokens(tokens
);
3767 if let Some((ref colon_token
, ref ty
)) = self.ty
{
3768 colon_token
.to_tokens(tokens
);
3769 ty
.to_tokens(tokens
);
3771 if let Some((ref eq_token
, ref init
)) = self.init
{
3772 eq_token
.to_tokens(tokens
);
3773 init
.to_tokens(tokens
);
3775 self.semi_token
.to_tokens(tokens
);