aboutsummaryrefslogtreecommitdiff
path: root/vendor/syn/src/expr.rs
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2024-07-19 15:37:58 +0300
committerValentin Popov <valentin@popov.link>2024-07-19 15:37:58 +0300
commita990de90fe41456a23e58bd087d2f107d321f3a1 (patch)
tree15afc392522a9e85dc3332235e311b7d39352ea9 /vendor/syn/src/expr.rs
parent3d48cd3f81164bbfc1a755dc1d4a9a02f98c8ddd (diff)
downloadfparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.tar.xz
fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.zip
Deleted vendor folder
Diffstat (limited to 'vendor/syn/src/expr.rs')
-rw-r--r--vendor/syn/src/expr.rs3506
1 files changed, 0 insertions, 3506 deletions
diff --git a/vendor/syn/src/expr.rs b/vendor/syn/src/expr.rs
deleted file mode 100644
index 7fb0f7b..0000000
--- a/vendor/syn/src/expr.rs
+++ /dev/null
@@ -1,3506 +0,0 @@
-use super::*;
-use crate::punctuated::Punctuated;
-use proc_macro2::{Span, TokenStream};
-#[cfg(feature = "printing")]
-use quote::IdentFragment;
-#[cfg(feature = "printing")]
-use std::fmt::{self, Display};
-use std::hash::{Hash, Hasher};
-#[cfg(feature = "parsing")]
-use std::mem;
-
-ast_enum_of_structs! {
- /// A Rust expression.
- ///
- /// *This type is available only if Syn is built with the `"derive"` or `"full"`
- /// feature, but most of the variants are not available unless "full" is enabled.*
- ///
- /// # Syntax tree enums
- ///
- /// This type is a syntax tree enum. In Syn this and other syntax tree enums
- /// are designed to be traversed using the following rebinding idiom.
- ///
- /// ```
- /// # use syn::Expr;
- /// #
- /// # fn example(expr: Expr) {
- /// # const IGNORE: &str = stringify! {
- /// let expr: Expr = /* ... */;
- /// # };
- /// match expr {
- /// Expr::MethodCall(expr) => {
- /// /* ... */
- /// }
- /// Expr::Cast(expr) => {
- /// /* ... */
- /// }
- /// Expr::If(expr) => {
- /// /* ... */
- /// }
- ///
- /// /* ... */
- /// # _ => {}
- /// # }
- /// # }
- /// ```
- ///
- /// We begin with a variable `expr` of type `Expr` that has no fields
- /// (because it is an enum), and by matching on it and rebinding a variable
- /// with the same name `expr` we effectively imbue our variable with all of
- /// the data fields provided by the variant that it turned out to be. So for
- /// example above if we ended up in the `MethodCall` case then we get to use
- /// `expr.receiver`, `expr.args` etc; if we ended up in the `If` case we get
- /// to use `expr.cond`, `expr.then_branch`, `expr.else_branch`.
- ///
- /// This approach avoids repeating the variant names twice on every line.
- ///
- /// ```
- /// # use syn::{Expr, ExprMethodCall};
- /// #
- /// # fn example(expr: Expr) {
- /// // Repetitive; recommend not doing this.
- /// match expr {
- /// Expr::MethodCall(ExprMethodCall { method, args, .. }) => {
- /// # }
- /// # _ => {}
- /// # }
- /// # }
- /// ```
- ///
- /// In general, the name to which a syntax tree enum variant is bound should
- /// be a suitable name for the complete syntax tree enum type.
- ///
- /// ```
- /// # use syn::{Expr, ExprField};
- /// #
- /// # fn example(discriminant: ExprField) {
- /// // Binding is called `base` which is the name I would use if I were
- /// // assigning `*discriminant.base` without an `if let`.
- /// if let Expr::Tuple(base) = *discriminant.base {
- /// # }
- /// # }
- /// ```
- ///
- /// A sign that you may not be choosing the right variable names is if you
- /// see names getting repeated in your code, like accessing
- /// `receiver.receiver` or `pat.pat` or `cond.cond`.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- #[non_exhaustive]
- pub enum Expr {
- /// A slice literal expression: `[a, b, c, d]`.
- Array(ExprArray),
-
- /// An assignment expression: `a = compute()`.
- Assign(ExprAssign),
-
- /// An async block: `async { ... }`.
- Async(ExprAsync),
-
- /// An await expression: `fut.await`.
- Await(ExprAwait),
-
- /// A binary operation: `a + b`, `a += b`.
- Binary(ExprBinary),
-
- /// A blocked scope: `{ ... }`.
- Block(ExprBlock),
-
- /// A `break`, with an optional label to break and an optional
- /// expression.
- Break(ExprBreak),
-
- /// A function call expression: `invoke(a, b)`.
- Call(ExprCall),
-
- /// A cast expression: `foo as f64`.
- Cast(ExprCast),
-
- /// A closure expression: `|a, b| a + b`.
- Closure(ExprClosure),
-
- /// A const block: `const { ... }`.
- Const(ExprConst),
-
- /// A `continue`, with an optional label.
- Continue(ExprContinue),
-
- /// Access of a named struct field (`obj.k`) or unnamed tuple struct
- /// field (`obj.0`).
- Field(ExprField),
-
- /// A for loop: `for pat in expr { ... }`.
- ForLoop(ExprForLoop),
-
- /// An expression contained within invisible delimiters.
- ///
- /// This variant is important for faithfully representing the precedence
- /// of expressions and is related to `None`-delimited spans in a
- /// `TokenStream`.
- Group(ExprGroup),
-
- /// An `if` expression with an optional `else` block: `if expr { ... }
- /// else { ... }`.
- ///
- /// The `else` branch expression may only be an `If` or `Block`
- /// expression, not any of the other types of expression.
- If(ExprIf),
-
- /// A square bracketed indexing expression: `vector[2]`.
- Index(ExprIndex),
-
- /// The inferred value of a const generic argument, denoted `_`.
- Infer(ExprInfer),
-
- /// A `let` guard: `let Some(x) = opt`.
- Let(ExprLet),
-
- /// A literal in place of an expression: `1`, `"foo"`.
- Lit(ExprLit),
-
- /// Conditionless loop: `loop { ... }`.
- Loop(ExprLoop),
-
- /// A macro invocation expression: `format!("{}", q)`.
- Macro(ExprMacro),
-
- /// A `match` expression: `match n { Some(n) => {}, None => {} }`.
- Match(ExprMatch),
-
- /// A method call expression: `x.foo::<T>(a, b)`.
- MethodCall(ExprMethodCall),
-
- /// A parenthesized expression: `(a + b)`.
- Paren(ExprParen),
-
- /// A path like `std::mem::replace` possibly containing generic
- /// parameters and a qualified self-type.
- ///
- /// A plain identifier like `x` is a path of length 1.
- Path(ExprPath),
-
- /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`.
- Range(ExprRange),
-
- /// A referencing operation: `&a` or `&mut a`.
- Reference(ExprReference),
-
- /// An array literal constructed from one repeated element: `[0u8; N]`.
- Repeat(ExprRepeat),
-
- /// A `return`, with an optional value to be returned.
- Return(ExprReturn),
-
- /// A struct literal expression: `Point { x: 1, y: 1 }`.
- ///
- /// The `rest` provides the value of the remaining fields as in `S { a:
- /// 1, b: 1, ..rest }`.
- Struct(ExprStruct),
-
- /// A try-expression: `expr?`.
- Try(ExprTry),
-
- /// A try block: `try { ... }`.
- TryBlock(ExprTryBlock),
-
- /// A tuple expression: `(a, b, c, d)`.
- Tuple(ExprTuple),
-
- /// A unary operation: `!x`, `*x`.
- Unary(ExprUnary),
-
- /// An unsafe block: `unsafe { ... }`.
- Unsafe(ExprUnsafe),
-
- /// Tokens in expression position not interpreted by Syn.
- Verbatim(TokenStream),
-
- /// A while loop: `while expr { ... }`.
- While(ExprWhile),
-
- /// A yield expression: `yield expr`.
- Yield(ExprYield),
-
- // For testing exhaustiveness in downstream code, use the following idiom:
- //
- // match expr {
- // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
- //
- // Expr::Array(expr) => {...}
- // Expr::Assign(expr) => {...}
- // ...
- // Expr::Yield(expr) => {...}
- //
- // _ => { /* some sane fallback */ }
- // }
- //
- // This way we fail your tests but don't break your library when adding
- // a variant. You will be notified by a test failure when a variant is
- // added, so that you can add code to handle it, but your library will
- // continue to compile and work for downstream users in the interim.
- }
-}
-
-ast_struct! {
- /// A slice literal expression: `[a, b, c, d]`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprArray #full {
- pub attrs: Vec<Attribute>,
- pub bracket_token: token::Bracket,
- pub elems: Punctuated<Expr, Token![,]>,
- }
-}
-
-ast_struct! {
- /// An assignment expression: `a = compute()`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprAssign #full {
- pub attrs: Vec<Attribute>,
- pub left: Box<Expr>,
- pub eq_token: Token![=],
- pub right: Box<Expr>,
- }
-}
-
-ast_struct! {
- /// An async block: `async { ... }`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprAsync #full {
- pub attrs: Vec<Attribute>,
- pub async_token: Token![async],
- pub capture: Option<Token![move]>,
- pub block: Block,
- }
-}
-
-ast_struct! {
- /// An await expression: `fut.await`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprAwait #full {
- pub attrs: Vec<Attribute>,
- pub base: Box<Expr>,
- pub dot_token: Token![.],
- pub await_token: Token![await],
- }
-}
-
-ast_struct! {
- /// A binary operation: `a + b`, `a += b`.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprBinary {
- pub attrs: Vec<Attribute>,
- pub left: Box<Expr>,
- pub op: BinOp,
- pub right: Box<Expr>,
- }
-}
-
-ast_struct! {
- /// A blocked scope: `{ ... }`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprBlock #full {
- pub attrs: Vec<Attribute>,
- pub label: Option<Label>,
- pub block: Block,
- }
-}
-
-ast_struct! {
- /// A `break`, with an optional label to break and an optional
- /// expression.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprBreak #full {
- pub attrs: Vec<Attribute>,
- pub break_token: Token![break],
- pub label: Option<Lifetime>,
- pub expr: Option<Box<Expr>>,
- }
-}
-
-ast_struct! {
- /// A function call expression: `invoke(a, b)`.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprCall {
- pub attrs: Vec<Attribute>,
- pub func: Box<Expr>,
- pub paren_token: token::Paren,
- pub args: Punctuated<Expr, Token![,]>,
- }
-}
-
-ast_struct! {
- /// A cast expression: `foo as f64`.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprCast {
- pub attrs: Vec<Attribute>,
- pub expr: Box<Expr>,
- pub as_token: Token![as],
- pub ty: Box<Type>,
- }
-}
-
-ast_struct! {
- /// A closure expression: `|a, b| a + b`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprClosure #full {
- pub attrs: Vec<Attribute>,
- pub lifetimes: Option<BoundLifetimes>,
- pub constness: Option<Token![const]>,
- pub movability: Option<Token![static]>,
- pub asyncness: Option<Token![async]>,
- pub capture: Option<Token![move]>,
- pub or1_token: Token![|],
- pub inputs: Punctuated<Pat, Token![,]>,
- pub or2_token: Token![|],
- pub output: ReturnType,
- pub body: Box<Expr>,
- }
-}
-
-ast_struct! {
- /// A const block: `const { ... }`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprConst #full {
- pub attrs: Vec<Attribute>,
- pub const_token: Token![const],
- pub block: Block,
- }
-}
-
-ast_struct! {
- /// A `continue`, with an optional label.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprContinue #full {
- pub attrs: Vec<Attribute>,
- pub continue_token: Token![continue],
- pub label: Option<Lifetime>,
- }
-}
-
-ast_struct! {
- /// Access of a named struct field (`obj.k`) or unnamed tuple struct
- /// field (`obj.0`).
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprField {
- pub attrs: Vec<Attribute>,
- pub base: Box<Expr>,
- pub dot_token: Token![.],
- pub member: Member,
- }
-}
-
-ast_struct! {
- /// A for loop: `for pat in expr { ... }`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprForLoop #full {
- pub attrs: Vec<Attribute>,
- pub label: Option<Label>,
- pub for_token: Token![for],
- pub pat: Box<Pat>,
- pub in_token: Token![in],
- pub expr: Box<Expr>,
- pub body: Block,
- }
-}
-
-ast_struct! {
- /// An expression contained within invisible delimiters.
- ///
- /// This variant is important for faithfully representing the precedence
- /// of expressions and is related to `None`-delimited spans in a
- /// `TokenStream`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprGroup {
- pub attrs: Vec<Attribute>,
- pub group_token: token::Group,
- pub expr: Box<Expr>,
- }
-}
-
-ast_struct! {
- /// An `if` expression with an optional `else` block: `if expr { ... }
- /// else { ... }`.
- ///
- /// The `else` branch expression may only be an `If` or `Block`
- /// expression, not any of the other types of expression.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprIf #full {
- pub attrs: Vec<Attribute>,
- pub if_token: Token![if],
- pub cond: Box<Expr>,
- pub then_branch: Block,
- pub else_branch: Option<(Token![else], Box<Expr>)>,
- }
-}
-
-ast_struct! {
- /// A square bracketed indexing expression: `vector[2]`.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprIndex {
- pub attrs: Vec<Attribute>,
- pub expr: Box<Expr>,
- pub bracket_token: token::Bracket,
- pub index: Box<Expr>,
- }
-}
-
-ast_struct! {
- /// The inferred value of a const generic argument, denoted `_`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprInfer #full {
- pub attrs: Vec<Attribute>,
- pub underscore_token: Token![_],
- }
-}
-
-ast_struct! {
- /// A `let` guard: `let Some(x) = opt`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprLet #full {
- pub attrs: Vec<Attribute>,
- pub let_token: Token![let],
- pub pat: Box<Pat>,
- pub eq_token: Token![=],
- pub expr: Box<Expr>,
- }
-}
-
-ast_struct! {
- /// A literal in place of an expression: `1`, `"foo"`.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprLit {
- pub attrs: Vec<Attribute>,
- pub lit: Lit,
- }
-}
-
-ast_struct! {
- /// Conditionless loop: `loop { ... }`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprLoop #full {
- pub attrs: Vec<Attribute>,
- pub label: Option<Label>,
- pub loop_token: Token![loop],
- pub body: Block,
- }
-}
-
-ast_struct! {
- /// A macro invocation expression: `format!("{}", q)`.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprMacro {
- pub attrs: Vec<Attribute>,
- pub mac: Macro,
- }
-}
-
-ast_struct! {
- /// A `match` expression: `match n { Some(n) => {}, None => {} }`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprMatch #full {
- pub attrs: Vec<Attribute>,
- pub match_token: Token![match],
- pub expr: Box<Expr>,
- pub brace_token: token::Brace,
- pub arms: Vec<Arm>,
- }
-}
-
-ast_struct! {
- /// A method call expression: `x.foo::<T>(a, b)`.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprMethodCall {
- pub attrs: Vec<Attribute>,
- pub receiver: Box<Expr>,
- pub dot_token: Token![.],
- pub method: Ident,
- pub turbofish: Option<AngleBracketedGenericArguments>,
- pub paren_token: token::Paren,
- pub args: Punctuated<Expr, Token![,]>,
- }
-}
-
-ast_struct! {
- /// A parenthesized expression: `(a + b)`.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprParen {
- pub attrs: Vec<Attribute>,
- pub paren_token: token::Paren,
- pub expr: Box<Expr>,
- }
-}
-
-ast_struct! {
- /// A path like `std::mem::replace` possibly containing generic
- /// parameters and a qualified self-type.
- ///
- /// A plain identifier like `x` is a path of length 1.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprPath {
- pub attrs: Vec<Attribute>,
- pub qself: Option<QSelf>,
- pub path: Path,
- }
-}
-
-ast_struct! {
- /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprRange #full {
- pub attrs: Vec<Attribute>,
- pub start: Option<Box<Expr>>,
- pub limits: RangeLimits,
- pub end: Option<Box<Expr>>,
- }
-}
-
-ast_struct! {
- /// A referencing operation: `&a` or `&mut a`.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprReference {
- pub attrs: Vec<Attribute>,
- pub and_token: Token![&],
- pub mutability: Option<Token![mut]>,
- pub expr: Box<Expr>,
- }
-}
-
-ast_struct! {
- /// An array literal constructed from one repeated element: `[0u8; N]`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprRepeat #full {
- pub attrs: Vec<Attribute>,
- pub bracket_token: token::Bracket,
- pub expr: Box<Expr>,
- pub semi_token: Token![;],
- pub len: Box<Expr>,
- }
-}
-
-ast_struct! {
- /// A `return`, with an optional value to be returned.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprReturn #full {
- pub attrs: Vec<Attribute>,
- pub return_token: Token![return],
- pub expr: Option<Box<Expr>>,
- }
-}
-
-ast_struct! {
- /// A struct literal expression: `Point { x: 1, y: 1 }`.
- ///
- /// The `rest` provides the value of the remaining fields as in `S { a:
- /// 1, b: 1, ..rest }`.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprStruct {
- pub attrs: Vec<Attribute>,
- pub qself: Option<QSelf>,
- pub path: Path,
- pub brace_token: token::Brace,
- pub fields: Punctuated<FieldValue, Token![,]>,
- pub dot2_token: Option<Token![..]>,
- pub rest: Option<Box<Expr>>,
- }
-}
-
-ast_struct! {
- /// A try-expression: `expr?`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprTry #full {
- pub attrs: Vec<Attribute>,
- pub expr: Box<Expr>,
- pub question_token: Token![?],
- }
-}
-
-ast_struct! {
- /// A try block: `try { ... }`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprTryBlock #full {
- pub attrs: Vec<Attribute>,
- pub try_token: Token![try],
- pub block: Block,
- }
-}
-
-ast_struct! {
- /// A tuple expression: `(a, b, c, d)`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprTuple #full {
- pub attrs: Vec<Attribute>,
- pub paren_token: token::Paren,
- pub elems: Punctuated<Expr, Token![,]>,
- }
-}
-
-ast_struct! {
- /// A unary operation: `!x`, `*x`.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct ExprUnary {
- pub attrs: Vec<Attribute>,
- pub op: UnOp,
- pub expr: Box<Expr>,
- }
-}
-
-ast_struct! {
- /// An unsafe block: `unsafe { ... }`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprUnsafe #full {
- pub attrs: Vec<Attribute>,
- pub unsafe_token: Token![unsafe],
- pub block: Block,
- }
-}
-
-ast_struct! {
- /// A while loop: `while expr { ... }`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprWhile #full {
- pub attrs: Vec<Attribute>,
- pub label: Option<Label>,
- pub while_token: Token![while],
- pub cond: Box<Expr>,
- pub body: Block,
- }
-}
-
-ast_struct! {
- /// A yield expression: `yield expr`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct ExprYield #full {
- pub attrs: Vec<Attribute>,
- pub yield_token: Token![yield],
- pub expr: Option<Box<Expr>>,
- }
-}
-
-impl Expr {
- #[cfg(feature = "parsing")]
- const DUMMY: Self = Expr::Path(ExprPath {
- attrs: Vec::new(),
- qself: None,
- path: Path {
- leading_colon: None,
- segments: Punctuated::new(),
- },
- });
-
- #[cfg(all(feature = "parsing", feature = "full"))]
- pub(crate) fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
- match self {
- Expr::Array(ExprArray { attrs, .. })
- | Expr::Assign(ExprAssign { attrs, .. })
- | Expr::Async(ExprAsync { attrs, .. })
- | Expr::Await(ExprAwait { attrs, .. })
- | Expr::Binary(ExprBinary { attrs, .. })
- | Expr::Block(ExprBlock { attrs, .. })
- | Expr::Break(ExprBreak { attrs, .. })
- | Expr::Call(ExprCall { attrs, .. })
- | Expr::Cast(ExprCast { attrs, .. })
- | Expr::Closure(ExprClosure { attrs, .. })
- | Expr::Const(ExprConst { attrs, .. })
- | Expr::Continue(ExprContinue { attrs, .. })
- | Expr::Field(ExprField { attrs, .. })
- | Expr::ForLoop(ExprForLoop { attrs, .. })
- | Expr::Group(ExprGroup { attrs, .. })
- | Expr::If(ExprIf { attrs, .. })
- | Expr::Index(ExprIndex { attrs, .. })
- | Expr::Infer(ExprInfer { attrs, .. })
- | Expr::Let(ExprLet { attrs, .. })
- | Expr::Lit(ExprLit { attrs, .. })
- | Expr::Loop(ExprLoop { attrs, .. })
- | Expr::Macro(ExprMacro { attrs, .. })
- | Expr::Match(ExprMatch { attrs, .. })
- | Expr::MethodCall(ExprMethodCall { attrs, .. })
- | Expr::Paren(ExprParen { attrs, .. })
- | Expr::Path(ExprPath { attrs, .. })
- | Expr::Range(ExprRange { attrs, .. })
- | Expr::Reference(ExprReference { attrs, .. })
- | Expr::Repeat(ExprRepeat { attrs, .. })
- | Expr::Return(ExprReturn { attrs, .. })
- | Expr::Struct(ExprStruct { attrs, .. })
- | Expr::Try(ExprTry { attrs, .. })
- | Expr::TryBlock(ExprTryBlock { attrs, .. })
- | Expr::Tuple(ExprTuple { attrs, .. })
- | Expr::Unary(ExprUnary { attrs, .. })
- | Expr::Unsafe(ExprUnsafe { attrs, .. })
- | Expr::While(ExprWhile { attrs, .. })
- | Expr::Yield(ExprYield { attrs, .. }) => mem::replace(attrs, new),
- Expr::Verbatim(_) => Vec::new(),
- }
- }
-}
-
-ast_enum! {
- /// A struct or tuple struct field accessed in a struct literal or field
- /// expression.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub enum Member {
- /// A named field like `self.x`.
- Named(Ident),
- /// An unnamed field like `self.0`.
- Unnamed(Index),
- }
-}
-
-impl From<Ident> for Member {
- fn from(ident: Ident) -> Member {
- Member::Named(ident)
- }
-}
-
-impl From<Index> for Member {
- fn from(index: Index) -> Member {
- Member::Unnamed(index)
- }
-}
-
-impl From<usize> for Member {
- fn from(index: usize) -> Member {
- Member::Unnamed(Index::from(index))
- }
-}
-
-impl Eq for Member {}
-
-impl PartialEq for Member {
- fn eq(&self, other: &Self) -> bool {
- match (self, other) {
- (Member::Named(this), Member::Named(other)) => this == other,
- (Member::Unnamed(this), Member::Unnamed(other)) => this == other,
- _ => false,
- }
- }
-}
-
-impl Hash for Member {
- fn hash<H: Hasher>(&self, state: &mut H) {
- match self {
- Member::Named(m) => m.hash(state),
- Member::Unnamed(m) => m.hash(state),
- }
- }
-}
-
-#[cfg(feature = "printing")]
-impl IdentFragment for Member {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- match self {
- Member::Named(m) => Display::fmt(m, formatter),
- Member::Unnamed(m) => Display::fmt(&m.index, formatter),
- }
- }
-
- fn span(&self) -> Option<Span> {
- match self {
- Member::Named(m) => Some(m.span()),
- Member::Unnamed(m) => Some(m.span),
- }
- }
-}
-
-ast_struct! {
- /// The index of an unnamed tuple struct field.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct Index {
- pub index: u32,
- pub span: Span,
- }
-}
-
-impl From<usize> for Index {
- fn from(index: usize) -> Index {
- assert!(index < u32::max_value() as usize);
- Index {
- index: index as u32,
- span: Span::call_site(),
- }
- }
-}
-
-impl Eq for Index {}
-
-impl PartialEq for Index {
- fn eq(&self, other: &Self) -> bool {
- self.index == other.index
- }
-}
-
-impl Hash for Index {
- fn hash<H: Hasher>(&self, state: &mut H) {
- self.index.hash(state);
- }
-}
-
-#[cfg(feature = "printing")]
-impl IdentFragment for Index {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- Display::fmt(&self.index, formatter)
- }
-
- fn span(&self) -> Option<Span> {
- Some(self.span)
- }
-}
-
-ast_struct! {
- /// A field-value pair in a struct literal.
- #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
- pub struct FieldValue {
- pub attrs: Vec<Attribute>,
- pub member: Member,
-
- /// The colon in `Struct { x: x }`. If written in shorthand like
- /// `Struct { x }`, there is no colon.
- pub colon_token: Option<Token![:]>,
-
- pub expr: Expr,
- }
-}
-
-#[cfg(feature = "full")]
-ast_struct! {
- /// A lifetime labeling a `for`, `while`, or `loop`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct Label {
- pub name: Lifetime,
- pub colon_token: Token![:],
- }
-}
-
-#[cfg(feature = "full")]
-ast_struct! {
- /// One arm of a `match` expression: `0..=10 => { return true; }`.
- ///
- /// As in:
- ///
- /// ```
- /// # fn f() -> bool {
- /// # let n = 0;
- /// match n {
- /// 0..=10 => {
- /// return true;
- /// }
- /// // ...
- /// # _ => {}
- /// }
- /// # false
- /// # }
- /// ```
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct Arm {
- pub attrs: Vec<Attribute>,
- pub pat: Pat,
- pub guard: Option<(Token![if], Box<Expr>)>,
- pub fat_arrow_token: Token![=>],
- pub body: Box<Expr>,
- pub comma: Option<Token![,]>,
- }
-}
-
-#[cfg(feature = "full")]
-ast_enum! {
- /// Limit types of a range, inclusive or exclusive.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub enum RangeLimits {
- /// Inclusive at the beginning, exclusive at the end.
- HalfOpen(Token![..]),
- /// Inclusive at the beginning and end.
- Closed(Token![..=]),
- }
-}
-
-#[cfg(any(feature = "parsing", feature = "printing"))]
-#[cfg(feature = "full")]
-pub(crate) fn requires_terminator(expr: &Expr) -> bool {
- // see https://github.com/rust-lang/rust/blob/9a19e7604/compiler/rustc_ast/src/util/classify.rs#L7-L26
- match expr {
- Expr::If(_)
- | Expr::Match(_)
- | Expr::Block(_) | Expr::Unsafe(_) // both under ExprKind::Block in rustc
- | Expr::While(_)
- | Expr::Loop(_)
- | Expr::ForLoop(_)
- | Expr::TryBlock(_)
- | Expr::Const(_) => false,
- Expr::Array(_)
- | Expr::Assign(_)
- | Expr::Async(_)
- | Expr::Await(_)
- | Expr::Binary(_)
- | Expr::Break(_)
- | Expr::Call(_)
- | Expr::Cast(_)
- | Expr::Closure(_)
- | Expr::Continue(_)
- | Expr::Field(_)
- | Expr::Group(_)
- | Expr::Index(_)
- | Expr::Infer(_)
- | Expr::Let(_)
- | Expr::Lit(_)
- | Expr::Macro(_)
- | Expr::MethodCall(_)
- | Expr::Paren(_)
- | Expr::Path(_)
- | Expr::Range(_)
- | Expr::Reference(_)
- | Expr::Repeat(_)
- | Expr::Return(_)
- | Expr::Struct(_)
- | Expr::Try(_)
- | Expr::Tuple(_)
- | Expr::Unary(_)
- | Expr::Yield(_)
- | Expr::Verbatim(_) => true
- }
-}
-
-#[cfg(feature = "parsing")]
-mod precedence {
- use super::BinOp;
-
- pub(crate) enum Precedence {
- Any,
- Assign,
- Range,
- Or,
- And,
- Compare,
- BitOr,
- BitXor,
- BitAnd,
- Shift,
- Arithmetic,
- Term,
- Cast,
- }
-
- impl Precedence {
- pub(crate) fn of(op: &BinOp) -> Self {
- match op {
- BinOp::Add(_) | BinOp::Sub(_) => Precedence::Arithmetic,
- BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Term,
- BinOp::And(_) => Precedence::And,
- BinOp::Or(_) => Precedence::Or,
- BinOp::BitXor(_) => Precedence::BitXor,
- BinOp::BitAnd(_) => Precedence::BitAnd,
- BinOp::BitOr(_) => Precedence::BitOr,
- BinOp::Shl(_) | BinOp::Shr(_) => Precedence::Shift,
- BinOp::Eq(_)
- | BinOp::Lt(_)
- | BinOp::Le(_)
- | BinOp::Ne(_)
- | BinOp::Ge(_)
- | BinOp::Gt(_) => Precedence::Compare,
- BinOp::AddAssign(_)
- | BinOp::SubAssign(_)
- | BinOp::MulAssign(_)
- | BinOp::DivAssign(_)
- | BinOp::RemAssign(_)
- | BinOp::BitXorAssign(_)
- | BinOp::BitAndAssign(_)
- | BinOp::BitOrAssign(_)
- | BinOp::ShlAssign(_)
- | BinOp::ShrAssign(_) => Precedence::Assign,
- }
- }
- }
-}
-
-#[cfg(feature = "parsing")]
-pub(crate) mod parsing {
- use super::precedence::Precedence;
- use super::*;
- #[cfg(feature = "full")]
- use crate::ext::IdentExt as _;
- use crate::parse::discouraged::Speculative as _;
- #[cfg(feature = "full")]
- use crate::parse::ParseBuffer;
- use crate::parse::{Parse, ParseStream, Result};
- use crate::path;
- use std::cmp::Ordering;
-
- mod kw {
- crate::custom_keyword!(builtin);
- crate::custom_keyword!(raw);
- }
-
- // When we're parsing expressions which occur before blocks, like in an if
- // statement's condition, we cannot parse a struct literal.
- //
- // Struct literals are ambiguous in certain positions
- // https://github.com/rust-lang/rfcs/pull/92
- #[cfg(feature = "full")]
- pub(crate) struct AllowStruct(bool);
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for Expr {
- fn parse(input: ParseStream) -> Result<Self> {
- ambiguous_expr(
- input,
- #[cfg(feature = "full")]
- AllowStruct(true),
- )
- }
- }
-
- impl Expr {
- /// An alternative to the primary `Expr::parse` parser (from the
- /// [`Parse`] trait) for ambiguous syntactic positions in which a
- /// trailing brace should not be taken as part of the expression.
- ///
- /// Rust grammar has an ambiguity where braces sometimes turn a path
- /// expression into a struct initialization and sometimes do not. In the
- /// following code, the expression `S {}` is one expression. Presumably
- /// there is an empty struct `struct S {}` defined somewhere which it is
- /// instantiating.
- ///
- /// ```
- /// # struct S;
- /// # impl std::ops::Deref for S {
- /// # type Target = bool;
- /// # fn deref(&self) -> &Self::Target {
- /// # &true
- /// # }
- /// # }
- /// let _ = *S {};
- ///
- /// // parsed by rustc as: `*(S {})`
- /// ```
- ///
- /// We would want to parse the above using `Expr::parse` after the `=`
- /// token.
- ///
- /// But in the following, `S {}` is *not* a struct init expression.
- ///
- /// ```
- /// # const S: &bool = &true;
- /// if *S {} {}
- ///
- /// // parsed by rustc as:
- /// //
- /// // if (*S) {
- /// // /* empty block */
- /// // }
- /// // {
- /// // /* another empty block */
- /// // }
- /// ```
- ///
- /// For that reason we would want to parse if-conditions using
- /// `Expr::parse_without_eager_brace` after the `if` token. Same for
- /// similar syntactic positions such as the condition expr after a
- /// `while` token or the expr at the top of a `match`.
- ///
- /// The Rust grammar's choices around which way this ambiguity is
- /// resolved at various syntactic positions is fairly arbitrary. Really
- /// either parse behavior could work in most positions, and language
- /// designers just decide each case based on which is more likely to be
- /// what the programmer had in mind most of the time.
- ///
- /// ```
- /// # struct S;
- /// # fn doc() -> S {
- /// if return S {} {}
- /// # unreachable!()
- /// # }
- ///
- /// // parsed by rustc as:
- /// //
- /// // if (return (S {})) {
- /// // }
- /// //
- /// // but could equally well have been this other arbitrary choice:
- /// //
- /// // if (return S) {
- /// // }
- /// // {}
- /// ```
- ///
- /// Note the grammar ambiguity on trailing braces is distinct from
- /// precedence and is not captured by assigning a precedence level to
- /// the braced struct init expr in relation to other operators. This can
- /// be illustrated by `return 0..S {}` vs `match 0..S {}`. The former
- /// parses as `return (0..(S {}))` implying tighter precedence for
- /// struct init than `..`, while the latter parses as `match (0..S) {}`
- /// implying tighter precedence for `..` than struct init, a
- /// contradiction.
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(all(feature = "full", feature = "parsing"))))]
- pub fn parse_without_eager_brace(input: ParseStream) -> Result<Expr> {
- ambiguous_expr(input, AllowStruct(false))
- }
- }
-
- #[cfg(feature = "full")]
- impl Copy for AllowStruct {}
-
- #[cfg(feature = "full")]
- impl Clone for AllowStruct {
- fn clone(&self) -> Self {
- *self
- }
- }
-
- impl Copy for Precedence {}
-
- impl Clone for Precedence {
- fn clone(&self) -> Self {
- *self
- }
- }
-
- impl PartialEq for Precedence {
- fn eq(&self, other: &Self) -> bool {
- *self as u8 == *other as u8
- }
- }
-
- impl PartialOrd for Precedence {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- let this = *self as u8;
- let other = *other as u8;
- Some(this.cmp(&other))
- }
- }
-
- #[cfg(feature = "full")]
- fn can_begin_expr(input: ParseStream) -> bool {
- input.peek(Ident::peek_any) // value name or keyword
- || input.peek(token::Paren) // tuple
- || input.peek(token::Bracket) // array
- || input.peek(token::Brace) // block
- || input.peek(Lit) // literal
- || input.peek(Token![!]) && !input.peek(Token![!=]) // operator not
- || input.peek(Token![-]) && !input.peek(Token![-=]) && !input.peek(Token![->]) // unary minus
- || input.peek(Token![*]) && !input.peek(Token![*=]) // dereference
- || input.peek(Token![|]) && !input.peek(Token![|=]) // closure
- || input.peek(Token![&]) && !input.peek(Token![&=]) // reference
- || input.peek(Token![..]) // range notation
- || input.peek(Token![<]) && !input.peek(Token![<=]) && !input.peek(Token![<<=]) // associated path
- || input.peek(Token![::]) // global path
- || input.peek(Lifetime) // labeled loop
- || input.peek(Token![#]) // expression attributes
- }
-
- #[cfg(feature = "full")]
- fn parse_expr(
- input: ParseStream,
- mut lhs: Expr,
- allow_struct: AllowStruct,
- base: Precedence,
- ) -> Result<Expr> {
- loop {
- let ahead = input.fork();
- if let Some(op) = match ahead.parse::<BinOp>() {
- Ok(op) if Precedence::of(&op) >= base => Some(op),
- _ => None,
- } {
- input.advance_to(&ahead);
- let precedence = Precedence::of(&op);
- let mut rhs = unary_expr(input, allow_struct)?;
- loop {
- let next = peek_precedence(input);
- if next > precedence || next == precedence && precedence == Precedence::Assign {
- rhs = parse_expr(input, rhs, allow_struct, next)?;
- } else {
- break;
- }
- }
- lhs = Expr::Binary(ExprBinary {
- attrs: Vec::new(),
- left: Box::new(lhs),
- op,
- right: Box::new(rhs),
- });
- } else if Precedence::Assign >= base
- && input.peek(Token![=])
- && !input.peek(Token![==])
- && !input.peek(Token![=>])
- {
- let eq_token: Token![=] = input.parse()?;
- let mut rhs = unary_expr(input, allow_struct)?;
- loop {
- let next = peek_precedence(input);
- if next >= Precedence::Assign {
- rhs = parse_expr(input, rhs, allow_struct, next)?;
- } else {
- break;
- }
- }
- lhs = Expr::Assign(ExprAssign {
- attrs: Vec::new(),
- left: Box::new(lhs),
- eq_token,
- right: Box::new(rhs),
- });
- } else if Precedence::Range >= base && input.peek(Token![..]) {
- let limits: RangeLimits = input.parse()?;
- let rhs = if matches!(limits, RangeLimits::HalfOpen(_))
- && (input.is_empty()
- || input.peek(Token![,])
- || input.peek(Token![;])
- || input.peek(Token![.]) && !input.peek(Token![..])
- || !allow_struct.0 && input.peek(token::Brace))
- {
- None
- } else {
- let mut rhs = unary_expr(input, allow_struct)?;
- loop {
- let next = peek_precedence(input);
- if next > Precedence::Range {
- rhs = parse_expr(input, rhs, allow_struct, next)?;
- } else {
- break;
- }
- }
- Some(rhs)
- };
- lhs = Expr::Range(ExprRange {
- attrs: Vec::new(),
- start: Some(Box::new(lhs)),
- limits,
- end: rhs.map(Box::new),
- });
- } else if Precedence::Cast >= base && input.peek(Token![as]) {
- let as_token: Token![as] = input.parse()?;
- let allow_plus = false;
- let allow_group_generic = false;
- let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?;
- check_cast(input)?;
- lhs = Expr::Cast(ExprCast {
- attrs: Vec::new(),
- expr: Box::new(lhs),
- as_token,
- ty: Box::new(ty),
- });
- } else {
- break;
- }
- }
- Ok(lhs)
- }
-
- #[cfg(not(feature = "full"))]
- fn parse_expr(input: ParseStream, mut lhs: Expr, base: Precedence) -> Result<Expr> {
- loop {
- let ahead = input.fork();
- if let Some(op) = match ahead.parse::<BinOp>() {
- Ok(op) if Precedence::of(&op) >= base => Some(op),
- _ => None,
- } {
- input.advance_to(&ahead);
- let precedence = Precedence::of(&op);
- let mut rhs = unary_expr(input)?;
- loop {
- let next = peek_precedence(input);
- if next > precedence || next == precedence && precedence == Precedence::Assign {
- rhs = parse_expr(input, rhs, next)?;
- } else {
- break;
- }
- }
- lhs = Expr::Binary(ExprBinary {
- attrs: Vec::new(),
- left: Box::new(lhs),
- op,
- right: Box::new(rhs),
- });
- } else if Precedence::Cast >= base && input.peek(Token![as]) {
- let as_token: Token![as] = input.parse()?;
- let allow_plus = false;
- let allow_group_generic = false;
- let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?;
- check_cast(input)?;
- lhs = Expr::Cast(ExprCast {
- attrs: Vec::new(),
- expr: Box::new(lhs),
- as_token,
- ty: Box::new(ty),
- });
- } else {
- break;
- }
- }
- Ok(lhs)
- }
-
- fn peek_precedence(input: ParseStream) -> Precedence {
- if let Ok(op) = input.fork().parse() {
- Precedence::of(&op)
- } else if input.peek(Token![=]) && !input.peek(Token![=>]) {
- Precedence::Assign
- } else if input.peek(Token![..]) {
- Precedence::Range
- } else if input.peek(Token![as]) {
- Precedence::Cast
- } else {
- Precedence::Any
- }
- }
-
- // Parse an arbitrary expression.
- fn ambiguous_expr(
- input: ParseStream,
- #[cfg(feature = "full")] allow_struct: AllowStruct,
- ) -> Result<Expr> {
- let lhs = unary_expr(
- input,
- #[cfg(feature = "full")]
- allow_struct,
- )?;
- parse_expr(
- input,
- lhs,
- #[cfg(feature = "full")]
- allow_struct,
- Precedence::Any,
- )
- }
-
- #[cfg(feature = "full")]
- fn expr_attrs(input: ParseStream) -> Result<Vec<Attribute>> {
- let mut attrs = Vec::new();
- while !input.peek(token::Group) && input.peek(Token![#]) {
- attrs.push(input.call(attr::parsing::single_parse_outer)?);
- }
- Ok(attrs)
- }
-
- // <UnOp> <trailer>
- // & <trailer>
- // &mut <trailer>
- // box <trailer>
- #[cfg(feature = "full")]
- fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
- let begin = input.fork();
- let attrs = input.call(expr_attrs)?;
- if input.peek(token::Group) {
- return trailer_expr(begin, attrs, input, allow_struct);
- }
-
- if input.peek(Token![&]) {
- let and_token: Token![&] = input.parse()?;
- let raw: Option<kw::raw> = if input.peek(kw::raw)
- && (input.peek2(Token![mut]) || input.peek2(Token![const]))
- {
- Some(input.parse()?)
- } else {
- None
- };
- let mutability: Option<Token![mut]> = input.parse()?;
- if raw.is_some() && mutability.is_none() {
- input.parse::<Token![const]>()?;
- }
- let expr = Box::new(unary_expr(input, allow_struct)?);
- if raw.is_some() {
- Ok(Expr::Verbatim(verbatim::between(&begin, input)))
- } else {
- Ok(Expr::Reference(ExprReference {
- attrs,
- and_token,
- mutability,
- expr,
- }))
- }
- } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
- expr_unary(input, attrs, allow_struct).map(Expr::Unary)
- } else {
- trailer_expr(begin, attrs, input, allow_struct)
- }
- }
-
- #[cfg(not(feature = "full"))]
- fn unary_expr(input: ParseStream) -> Result<Expr> {
- if input.peek(Token![&]) {
- Ok(Expr::Reference(ExprReference {
- attrs: Vec::new(),
- and_token: input.parse()?,
- mutability: input.parse()?,
- expr: Box::new(unary_expr(input)?),
- }))
- } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
- Ok(Expr::Unary(ExprUnary {
- attrs: Vec::new(),
- op: input.parse()?,
- expr: Box::new(unary_expr(input)?),
- }))
- } else {
- trailer_expr(input)
- }
- }
-
- // <atom> (..<args>) ...
- // <atom> . <ident> (..<args>) ...
- // <atom> . <ident> ...
- // <atom> . <lit> ...
- // <atom> [ <expr> ] ...
- // <atom> ? ...
- #[cfg(feature = "full")]
- fn trailer_expr(
- begin: ParseBuffer,
- mut attrs: Vec<Attribute>,
- input: ParseStream,
- allow_struct: AllowStruct,
- ) -> Result<Expr> {
- let atom = atom_expr(input, allow_struct)?;
- let mut e = trailer_helper(input, atom)?;
-
- if let Expr::Verbatim(tokens) = &mut e {
- *tokens = verbatim::between(&begin, input);
- } else {
- let inner_attrs = e.replace_attrs(Vec::new());
- attrs.extend(inner_attrs);
- e.replace_attrs(attrs);
- }
-
- Ok(e)
- }
-
- #[cfg(feature = "full")]
- fn trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr> {
- loop {
- if input.peek(token::Paren) {
- let content;
- e = Expr::Call(ExprCall {
- attrs: Vec::new(),
- func: Box::new(e),
- paren_token: parenthesized!(content in input),
- args: content.parse_terminated(Expr::parse, Token![,])?,
- });
- } else if input.peek(Token![.])
- && !input.peek(Token![..])
- && match e {
- Expr::Range(_) => false,
- _ => true,
- }
- {
- let mut dot_token: Token![.] = input.parse()?;
-
- let float_token: Option<LitFloat> = input.parse()?;
- if let Some(float_token) = float_token {
- if multi_index(&mut e, &mut dot_token, float_token)? {
- continue;
- }
- }
-
- let await_token: Option<Token![await]> = input.parse()?;
- if let Some(await_token) = await_token {
- e = Expr::Await(ExprAwait {
- attrs: Vec::new(),
- base: Box::new(e),
- dot_token,
- await_token,
- });
- continue;
- }
-
- let member: Member = input.parse()?;
- let turbofish = if member.is_named() && input.peek(Token![::]) {
- Some(AngleBracketedGenericArguments::parse_turbofish(input)?)
- } else {
- None
- };
-
- if turbofish.is_some() || input.peek(token::Paren) {
- if let Member::Named(method) = member {
- let content;
- e = Expr::MethodCall(ExprMethodCall {
- attrs: Vec::new(),
- receiver: Box::new(e),
- dot_token,
- method,
- turbofish,
- paren_token: parenthesized!(content in input),
- args: content.parse_terminated(Expr::parse, Token![,])?,
- });
- continue;
- }
- }
-
- e = Expr::Field(ExprField {
- attrs: Vec::new(),
- base: Box::new(e),
- dot_token,
- member,
- });
- } else if input.peek(token::Bracket) {
- let content;
- e = Expr::Index(ExprIndex {
- attrs: Vec::new(),
- expr: Box::new(e),
- bracket_token: bracketed!(content in input),
- index: content.parse()?,
- });
- } else if input.peek(Token![?]) {
- e = Expr::Try(ExprTry {
- attrs: Vec::new(),
- expr: Box::new(e),
- question_token: input.parse()?,
- });
- } else {
- break;
- }
- }
- Ok(e)
- }
-
- #[cfg(not(feature = "full"))]
- fn trailer_expr(input: ParseStream) -> Result<Expr> {
- let mut e = atom_expr(input)?;
-
- loop {
- if input.peek(token::Paren) {
- let content;
- e = Expr::Call(ExprCall {
- attrs: Vec::new(),
- func: Box::new(e),
- paren_token: parenthesized!(content in input),
- args: content.parse_terminated(Expr::parse, Token![,])?,
- });
- } else if input.peek(Token![.])
- && !input.peek(Token![..])
- && !input.peek2(Token![await])
- {
- let mut dot_token: Token![.] = input.parse()?;
-
- let float_token: Option<LitFloat> = input.parse()?;
- if let Some(float_token) = float_token {
- if multi_index(&mut e, &mut dot_token, float_token)? {
- continue;
- }
- }
-
- let member: Member = input.parse()?;
- let turbofish = if member.is_named() && input.peek(Token![::]) {
- let colon2_token: Token![::] = input.parse()?;
- let turbofish =
- AngleBracketedGenericArguments::do_parse(Some(colon2_token), input)?;
- Some(turbofish)
- } else {
- None
- };
-
- if turbofish.is_some() || input.peek(token::Paren) {
- if let Member::Named(method) = member {
- let content;
- e = Expr::MethodCall(ExprMethodCall {
- attrs: Vec::new(),
- receiver: Box::new(e),
- dot_token,
- method,
- turbofish,
- paren_token: parenthesized!(content in input),
- args: content.parse_terminated(Expr::parse, Token![,])?,
- });
- continue;
- }
- }
-
- e = Expr::Field(ExprField {
- attrs: Vec::new(),
- base: Box::new(e),
- dot_token,
- member,
- });
- } else if input.peek(token::Bracket) {
- let content;
- e = Expr::Index(ExprIndex {
- attrs: Vec::new(),
- expr: Box::new(e),
- bracket_token: bracketed!(content in input),
- index: content.parse()?,
- });
- } else {
- break;
- }
- }
-
- Ok(e)
- }
-
- // Parse all atomic expressions which don't have to worry about precedence
- // interactions, as they are fully contained.
- #[cfg(feature = "full")]
- fn atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
- if input.peek(token::Group) {
- expr_group(input, allow_struct)
- } else if input.peek(Lit) {
- input.parse().map(Expr::Lit)
- } else if input.peek(Token![async])
- && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace))
- {
- input.parse().map(Expr::Async)
- } else if input.peek(Token![try]) && input.peek2(token::Brace) {
- input.parse().map(Expr::TryBlock)
- } else if input.peek(Token![|])
- || input.peek(Token![move])
- || input.peek(Token![for])
- && input.peek2(Token![<])
- && (input.peek3(Lifetime) || input.peek3(Token![>]))
- || input.peek(Token![const]) && !input.peek2(token::Brace)
- || input.peek(Token![static])
- || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move]))
- {
- expr_closure(input, allow_struct).map(Expr::Closure)
- } else if input.peek(kw::builtin) && input.peek2(Token![#]) {
- expr_builtin(input)
- } else if input.peek(Ident)
- || input.peek(Token![::])
- || input.peek(Token![<])
- || input.peek(Token![self])
- || input.peek(Token![Self])
- || input.peek(Token![super])
- || input.peek(Token![crate])
- || input.peek(Token![try]) && (input.peek2(Token![!]) || input.peek2(Token![::]))
- {
- path_or_macro_or_struct(input, allow_struct)
- } else if input.peek(token::Paren) {
- paren_or_tuple(input)
- } else if input.peek(Token![break]) {
- expr_break(input, allow_struct).map(Expr::Break)
- } else if input.peek(Token![continue]) {
- input.parse().map(Expr::Continue)
- } else if input.peek(Token![return]) {
- expr_return(input, allow_struct).map(Expr::Return)
- } else if input.peek(token::Bracket) {
- array_or_repeat(input)
- } else if input.peek(Token![let]) {
- input.parse().map(Expr::Let)
- } else if input.peek(Token![if]) {
- input.parse().map(Expr::If)
- } else if input.peek(Token![while]) {
- input.parse().map(Expr::While)
- } else if input.peek(Token![for]) {
- input.parse().map(Expr::ForLoop)
- } else if input.peek(Token![loop]) {
- input.parse().map(Expr::Loop)
- } else if input.peek(Token![match]) {
- input.parse().map(Expr::Match)
- } else if input.peek(Token![yield]) {
- input.parse().map(Expr::Yield)
- } else if input.peek(Token![unsafe]) {
- input.parse().map(Expr::Unsafe)
- } else if input.peek(Token![const]) {
- input.parse().map(Expr::Const)
- } else if input.peek(token::Brace) {
- input.parse().map(Expr::Block)
- } else if input.peek(Token![..]) {
- expr_range(input, allow_struct).map(Expr::Range)
- } else if input.peek(Token![_]) {
- input.parse().map(Expr::Infer)
- } else if input.peek(Lifetime) {
- atom_labeled(input)
- } else {
- Err(input.error("expected an expression"))
- }
- }
-
- #[cfg(feature = "full")]
- fn atom_labeled(input: ParseStream) -> Result<Expr> {
- let the_label: Label = input.parse()?;
- let mut expr = if input.peek(Token![while]) {
- Expr::While(input.parse()?)
- } else if input.peek(Token![for]) {
- Expr::ForLoop(input.parse()?)
- } else if input.peek(Token![loop]) {
- Expr::Loop(input.parse()?)
- } else if input.peek(token::Brace) {
- Expr::Block(input.parse()?)
- } else {
- return Err(input.error("expected loop or block expression"));
- };
- match &mut expr {
- Expr::While(ExprWhile { label, .. })
- | Expr::ForLoop(ExprForLoop { label, .. })
- | Expr::Loop(ExprLoop { label, .. })
- | Expr::Block(ExprBlock { label, .. }) => *label = Some(the_label),
- _ => unreachable!(),
- }
- Ok(expr)
- }
-
- #[cfg(not(feature = "full"))]
- fn atom_expr(input: ParseStream) -> Result<Expr> {
- if input.peek(token::Group) {
- expr_group(input)
- } else if input.peek(Lit) {
- input.parse().map(Expr::Lit)
- } else if input.peek(token::Paren) {
- input.call(expr_paren).map(Expr::Paren)
- } else if input.peek(Ident)
- || input.peek(Token![::])
- || input.peek(Token![<])
- || input.peek(Token![self])
- || input.peek(Token![Self])
- || input.peek(Token![super])
- || input.peek(Token![crate])
- {
- path_or_macro_or_struct(input)
- } else if input.is_empty() {
- Err(input.error("expected an expression"))
- } else {
- if input.peek(token::Brace) {
- let scan = input.fork();
- let content;
- braced!(content in scan);
- if content.parse::<Expr>().is_ok() && content.is_empty() {
- let expr_block = verbatim::between(input, &scan);
- input.advance_to(&scan);
- return Ok(Expr::Verbatim(expr_block));
- }
- }
- Err(input.error("unsupported expression; enable syn's features=[\"full\"]"))
- }
- }
-
- #[cfg(feature = "full")]
- fn expr_builtin(input: ParseStream) -> Result<Expr> {
- let begin = input.fork();
-
- input.parse::<kw::builtin>()?;
- input.parse::<Token![#]>()?;
- input.parse::<Ident>()?;
-
- let args;
- parenthesized!(args in input);
- args.parse::<TokenStream>()?;
-
- Ok(Expr::Verbatim(verbatim::between(&begin, input)))
- }
-
- fn path_or_macro_or_struct(
- input: ParseStream,
- #[cfg(feature = "full")] allow_struct: AllowStruct,
- ) -> Result<Expr> {
- let (qself, path) = path::parsing::qpath(input, true)?;
- rest_of_path_or_macro_or_struct(
- qself,
- path,
- input,
- #[cfg(feature = "full")]
- allow_struct,
- )
- }
-
- fn rest_of_path_or_macro_or_struct(
- qself: Option<QSelf>,
- path: Path,
- input: ParseStream,
- #[cfg(feature = "full")] allow_struct: AllowStruct,
- ) -> Result<Expr> {
- if qself.is_none()
- && input.peek(Token![!])
- && !input.peek(Token![!=])
- && path.is_mod_style()
- {
- let bang_token: Token![!] = input.parse()?;
- let (delimiter, tokens) = mac::parse_delimiter(input)?;
- return Ok(Expr::Macro(ExprMacro {
- attrs: Vec::new(),
- mac: Macro {
- path,
- bang_token,
- delimiter,
- tokens,
- },
- }));
- }
-
- #[cfg(not(feature = "full"))]
- let allow_struct = (true,);
- if allow_struct.0 && input.peek(token::Brace) {
- return expr_struct_helper(input, qself, path).map(Expr::Struct);
- }
-
- Ok(Expr::Path(ExprPath {
- attrs: Vec::new(),
- qself,
- path,
- }))
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprMacro {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ExprMacro {
- attrs: Vec::new(),
- mac: input.parse()?,
- })
- }
- }
-
- #[cfg(feature = "full")]
- fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
- let content;
- let paren_token = parenthesized!(content in input);
- if content.is_empty() {
- return Ok(Expr::Tuple(ExprTuple {
- attrs: Vec::new(),
- paren_token,
- elems: Punctuated::new(),
- }));
- }
-
- let first: Expr = content.parse()?;
- if content.is_empty() {
- return Ok(Expr::Paren(ExprParen {
- attrs: Vec::new(),
- paren_token,
- expr: Box::new(first),
- }));
- }
-
- let mut elems = Punctuated::new();
- elems.push_value(first);
- while !content.is_empty() {
- let punct = content.parse()?;
- elems.push_punct(punct);
- if content.is_empty() {
- break;
- }
- let value = content.parse()?;
- elems.push_value(value);
- }
- Ok(Expr::Tuple(ExprTuple {
- attrs: Vec::new(),
- paren_token,
- elems,
- }))
- }
-
- #[cfg(feature = "full")]
- fn array_or_repeat(input: ParseStream) -> Result<Expr> {
- let content;
- let bracket_token = bracketed!(content in input);
- if content.is_empty() {
- return Ok(Expr::Array(ExprArray {
- attrs: Vec::new(),
- bracket_token,
- elems: Punctuated::new(),
- }));
- }
-
- let first: Expr = content.parse()?;
- if content.is_empty() || content.peek(Token![,]) {
- let mut elems = Punctuated::new();
- elems.push_value(first);
- while !content.is_empty() {
- let punct = content.parse()?;
- elems.push_punct(punct);
- if content.is_empty() {
- break;
- }
- let value = content.parse()?;
- elems.push_value(value);
- }
- Ok(Expr::Array(ExprArray {
- attrs: Vec::new(),
- bracket_token,
- elems,
- }))
- } else if content.peek(Token![;]) {
- let semi_token: Token![;] = content.parse()?;
- let len: Expr = content.parse()?;
- Ok(Expr::Repeat(ExprRepeat {
- attrs: Vec::new(),
- bracket_token,
- expr: Box::new(first),
- semi_token,
- len: Box::new(len),
- }))
- } else {
- Err(content.error("expected `,` or `;`"))
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprArray {
- fn parse(input: ParseStream) -> Result<Self> {
- let content;
- let bracket_token = bracketed!(content in input);
- let mut elems = Punctuated::new();
-
- while !content.is_empty() {
- let first: Expr = content.parse()?;
- elems.push_value(first);
- if content.is_empty() {
- break;
- }
- let punct = content.parse()?;
- elems.push_punct(punct);
- }
-
- Ok(ExprArray {
- attrs: Vec::new(),
- bracket_token,
- elems,
- })
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprRepeat {
- fn parse(input: ParseStream) -> Result<Self> {
- let content;
- Ok(ExprRepeat {
- bracket_token: bracketed!(content in input),
- attrs: Vec::new(),
- expr: content.parse()?,
- semi_token: content.parse()?,
- len: content.parse()?,
- })
- }
- }
-
- #[cfg(feature = "full")]
- pub(crate) fn expr_early(input: ParseStream) -> Result<Expr> {
- let mut attrs = input.call(expr_attrs)?;
- let mut expr = if input.peek(token::Group) {
- let allow_struct = AllowStruct(true);
- let atom = expr_group(input, allow_struct)?;
- if continue_parsing_early(&atom) {
- trailer_helper(input, atom)?
- } else {
- atom
- }
- } else if input.peek(Token![if]) {
- Expr::If(input.parse()?)
- } else if input.peek(Token![while]) {
- Expr::While(input.parse()?)
- } else if input.peek(Token![for])
- && !(input.peek2(Token![<]) && (input.peek3(Lifetime) || input.peek3(Token![>])))
- {
- Expr::ForLoop(input.parse()?)
- } else if input.peek(Token![loop]) {
- Expr::Loop(input.parse()?)
- } else if input.peek(Token![match]) {
- Expr::Match(input.parse()?)
- } else if input.peek(Token![try]) && input.peek2(token::Brace) {
- Expr::TryBlock(input.parse()?)
- } else if input.peek(Token![unsafe]) {
- Expr::Unsafe(input.parse()?)
- } else if input.peek(Token![const]) && input.peek2(token::Brace) {
- Expr::Const(input.parse()?)
- } else if input.peek(token::Brace) {
- Expr::Block(input.parse()?)
- } else if input.peek(Lifetime) {
- atom_labeled(input)?
- } else {
- let allow_struct = AllowStruct(true);
- unary_expr(input, allow_struct)?
- };
-
- if continue_parsing_early(&expr) {
- attrs.extend(expr.replace_attrs(Vec::new()));
- expr.replace_attrs(attrs);
-
- let allow_struct = AllowStruct(true);
- return parse_expr(input, expr, allow_struct, Precedence::Any);
- }
-
- if input.peek(Token![.]) && !input.peek(Token![..]) || input.peek(Token![?]) {
- expr = trailer_helper(input, expr)?;
-
- attrs.extend(expr.replace_attrs(Vec::new()));
- expr.replace_attrs(attrs);
-
- let allow_struct = AllowStruct(true);
- return parse_expr(input, expr, allow_struct, Precedence::Any);
- }
-
- attrs.extend(expr.replace_attrs(Vec::new()));
- expr.replace_attrs(attrs);
- Ok(expr)
- }
-
- #[cfg(feature = "full")]
- fn continue_parsing_early(mut expr: &Expr) -> bool {
- while let Expr::Group(group) = expr {
- expr = &group.expr;
- }
- match expr {
- Expr::If(_)
- | Expr::While(_)
- | Expr::ForLoop(_)
- | Expr::Loop(_)
- | Expr::Match(_)
- | Expr::TryBlock(_)
- | Expr::Unsafe(_)
- | Expr::Const(_)
- | Expr::Block(_) => false,
- _ => true,
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprLit {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ExprLit {
- attrs: Vec::new(),
- lit: input.parse()?,
- })
- }
- }
-
- fn expr_group(
- input: ParseStream,
- #[cfg(feature = "full")] allow_struct: AllowStruct,
- ) -> Result<Expr> {
- let group = crate::group::parse_group(input)?;
- let mut inner: Expr = group.content.parse()?;
-
- match inner {
- Expr::Path(mut expr) if expr.attrs.is_empty() => {
- let grouped_len = expr.path.segments.len();
- Path::parse_rest(input, &mut expr.path, true)?;
- match rest_of_path_or_macro_or_struct(
- expr.qself,
- expr.path,
- input,
- #[cfg(feature = "full")]
- allow_struct,
- )? {
- Expr::Path(expr) if expr.path.segments.len() == grouped_len => {
- inner = Expr::Path(expr);
- }
- extended => return Ok(extended),
- }
- }
- _ => {}
- }
-
- Ok(Expr::Group(ExprGroup {
- attrs: Vec::new(),
- group_token: group.token,
- expr: Box::new(inner),
- }))
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprParen {
- fn parse(input: ParseStream) -> Result<Self> {
- expr_paren(input)
- }
- }
-
- fn expr_paren(input: ParseStream) -> Result<ExprParen> {
- let content;
- Ok(ExprParen {
- attrs: Vec::new(),
- paren_token: parenthesized!(content in input),
- expr: content.parse()?,
- })
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprLet {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ExprLet {
- attrs: Vec::new(),
- let_token: input.parse()?,
- pat: Box::new(Pat::parse_multi_with_leading_vert(input)?),
- eq_token: input.parse()?,
- expr: Box::new({
- let allow_struct = AllowStruct(false);
- let lhs = unary_expr(input, allow_struct)?;
- parse_expr(input, lhs, allow_struct, Precedence::Compare)?
- }),
- })
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprIf {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- Ok(ExprIf {
- attrs,
- if_token: input.parse()?,
- cond: Box::new(input.call(Expr::parse_without_eager_brace)?),
- then_branch: input.parse()?,
- else_branch: {
- if input.peek(Token![else]) {
- Some(input.call(else_block)?)
- } else {
- None
- }
- },
- })
- }
- }
-
- #[cfg(feature = "full")]
- fn else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)> {
- let else_token: Token![else] = input.parse()?;
-
- let lookahead = input.lookahead1();
- let else_branch = if lookahead.peek(Token![if]) {
- input.parse().map(Expr::If)?
- } else if lookahead.peek(token::Brace) {
- Expr::Block(ExprBlock {
- attrs: Vec::new(),
- label: None,
- block: input.parse()?,
- })
- } else {
- return Err(lookahead.error());
- };
-
- Ok((else_token, Box::new(else_branch)))
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprInfer {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ExprInfer {
- attrs: input.call(Attribute::parse_outer)?,
- underscore_token: input.parse()?,
- })
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprForLoop {
- fn parse(input: ParseStream) -> Result<Self> {
- let mut attrs = input.call(Attribute::parse_outer)?;
- let label: Option<Label> = input.parse()?;
- let for_token: Token![for] = input.parse()?;
-
- let pat = Pat::parse_multi_with_leading_vert(input)?;
-
- let in_token: Token![in] = input.parse()?;
- let expr: Expr = input.call(Expr::parse_without_eager_brace)?;
-
- let content;
- let brace_token = braced!(content in input);
- attr::parsing::parse_inner(&content, &mut attrs)?;
- let stmts = content.call(Block::parse_within)?;
-
- Ok(ExprForLoop {
- attrs,
- label,
- for_token,
- pat: Box::new(pat),
- in_token,
- expr: Box::new(expr),
- body: Block { brace_token, stmts },
- })
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprLoop {
- fn parse(input: ParseStream) -> Result<Self> {
- let mut attrs = input.call(Attribute::parse_outer)?;
- let label: Option<Label> = input.parse()?;
- let loop_token: Token![loop] = input.parse()?;
-
- let content;
- let brace_token = braced!(content in input);
- attr::parsing::parse_inner(&content, &mut attrs)?;
- let stmts = content.call(Block::parse_within)?;
-
- Ok(ExprLoop {
- attrs,
- label,
- loop_token,
- body: Block { brace_token, stmts },
- })
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprMatch {
- fn parse(input: ParseStream) -> Result<Self> {
- let mut attrs = input.call(Attribute::parse_outer)?;
- let match_token: Token![match] = input.parse()?;
- let expr = Expr::parse_without_eager_brace(input)?;
-
- let content;
- let brace_token = braced!(content in input);
- attr::parsing::parse_inner(&content, &mut attrs)?;
-
- let mut arms = Vec::new();
- while !content.is_empty() {
- arms.push(content.call(Arm::parse)?);
- }
-
- Ok(ExprMatch {
- attrs,
- match_token,
- expr: Box::new(expr),
- brace_token,
- arms,
- })
- }
- }
-
- macro_rules! impl_by_parsing_expr {
- (
- $(
- $expr_type:ty, $variant:ident, $msg:expr,
- )*
- ) => {
- $(
- #[cfg(all(feature = "full", feature = "printing"))]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for $expr_type {
- fn parse(input: ParseStream) -> Result<Self> {
- let mut expr: Expr = input.parse()?;
- loop {
- match expr {
- Expr::$variant(inner) => return Ok(inner),
- Expr::Group(next) => expr = *next.expr,
- _ => return Err(Error::new_spanned(expr, $msg)),
- }
- }
- }
- }
- )*
- };
- }
-
- impl_by_parsing_expr! {
- ExprAssign, Assign, "expected assignment expression",
- ExprAwait, Await, "expected await expression",
- ExprBinary, Binary, "expected binary operation",
- ExprCall, Call, "expected function call expression",
- ExprCast, Cast, "expected cast expression",
- ExprField, Field, "expected struct field access",
- ExprIndex, Index, "expected indexing expression",
- ExprMethodCall, MethodCall, "expected method call expression",
- ExprRange, Range, "expected range expression",
- ExprTry, Try, "expected try expression",
- ExprTuple, Tuple, "expected tuple expression",
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprUnary {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = Vec::new();
- let allow_struct = AllowStruct(true);
- expr_unary(input, attrs, allow_struct)
- }
- }
-
- #[cfg(feature = "full")]
- fn expr_unary(
- input: ParseStream,
- attrs: Vec<Attribute>,
- allow_struct: AllowStruct,
- ) -> Result<ExprUnary> {
- Ok(ExprUnary {
- attrs,
- op: input.parse()?,
- expr: Box::new(unary_expr(input, allow_struct)?),
- })
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprClosure {
- fn parse(input: ParseStream) -> Result<Self> {
- let allow_struct = AllowStruct(true);
- expr_closure(input, allow_struct)
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprReference {
- fn parse(input: ParseStream) -> Result<Self> {
- let allow_struct = AllowStruct(true);
- Ok(ExprReference {
- attrs: Vec::new(),
- and_token: input.parse()?,
- mutability: input.parse()?,
- expr: Box::new(unary_expr(input, allow_struct)?),
- })
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprBreak {
- fn parse(input: ParseStream) -> Result<Self> {
- let allow_struct = AllowStruct(true);
- expr_break(input, allow_struct)
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprReturn {
- fn parse(input: ParseStream) -> Result<Self> {
- let allow_struct = AllowStruct(true);
- expr_return(input, allow_struct)
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprTryBlock {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ExprTryBlock {
- attrs: Vec::new(),
- try_token: input.parse()?,
- block: input.parse()?,
- })
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprYield {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ExprYield {
- attrs: Vec::new(),
- yield_token: input.parse()?,
- expr: {
- if can_begin_expr(input) {
- Some(input.parse()?)
- } else {
- None
- }
- },
- })
- }
- }
-
- #[cfg(feature = "full")]
- fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
- let lifetimes: Option<BoundLifetimes> = input.parse()?;
- let constness: Option<Token![const]> = input.parse()?;
- let movability: Option<Token![static]> = input.parse()?;
- let asyncness: Option<Token![async]> = input.parse()?;
- let capture: Option<Token![move]> = input.parse()?;
- let or1_token: Token![|] = input.parse()?;
-
- let mut inputs = Punctuated::new();
- loop {
- if input.peek(Token![|]) {
- break;
- }
- let value = closure_arg(input)?;
- inputs.push_value(value);
- if input.peek(Token![|]) {
- break;
- }
- let punct: Token![,] = input.parse()?;
- inputs.push_punct(punct);
- }
-
- let or2_token: Token![|] = input.parse()?;
-
- let (output, body) = if input.peek(Token![->]) {
- let arrow_token: Token![->] = input.parse()?;
- let ty: Type = input.parse()?;
- let body: Block = input.parse()?;
- let output = ReturnType::Type(arrow_token, Box::new(ty));
- let block = Expr::Block(ExprBlock {
- attrs: Vec::new(),
- label: None,
- block: body,
- });
- (output, block)
- } else {
- let body = ambiguous_expr(input, allow_struct)?;
- (ReturnType::Default, body)
- };
-
- Ok(ExprClosure {
- attrs: Vec::new(),
- lifetimes,
- constness,
- movability,
- asyncness,
- capture,
- or1_token,
- inputs,
- or2_token,
- output,
- body: Box::new(body),
- })
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprAsync {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ExprAsync {
- attrs: Vec::new(),
- async_token: input.parse()?,
- capture: input.parse()?,
- block: input.parse()?,
- })
- }
- }
-
- #[cfg(feature = "full")]
- fn closure_arg(input: ParseStream) -> Result<Pat> {
- let attrs = input.call(Attribute::parse_outer)?;
- let mut pat = Pat::parse_single(input)?;
-
- if input.peek(Token![:]) {
- Ok(Pat::Type(PatType {
- attrs,
- pat: Box::new(pat),
- colon_token: input.parse()?,
- ty: input.parse()?,
- }))
- } else {
- match &mut pat {
- Pat::Const(pat) => pat.attrs = attrs,
- Pat::Ident(pat) => pat.attrs = attrs,
- Pat::Lit(pat) => pat.attrs = attrs,
- Pat::Macro(pat) => pat.attrs = attrs,
- Pat::Or(pat) => pat.attrs = attrs,
- Pat::Paren(pat) => pat.attrs = attrs,
- Pat::Path(pat) => pat.attrs = attrs,
- Pat::Range(pat) => pat.attrs = attrs,
- Pat::Reference(pat) => pat.attrs = attrs,
- Pat::Rest(pat) => pat.attrs = attrs,
- Pat::Slice(pat) => pat.attrs = attrs,
- Pat::Struct(pat) => pat.attrs = attrs,
- Pat::Tuple(pat) => pat.attrs = attrs,
- Pat::TupleStruct(pat) => pat.attrs = attrs,
- Pat::Type(_) => unreachable!(),
- Pat::Verbatim(_) => {}
- Pat::Wild(pat) => pat.attrs = attrs,
- }
- Ok(pat)
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprWhile {
- fn parse(input: ParseStream) -> Result<Self> {
- let mut attrs = input.call(Attribute::parse_outer)?;
- let label: Option<Label> = input.parse()?;
- let while_token: Token![while] = input.parse()?;
- let cond = Expr::parse_without_eager_brace(input)?;
-
- let content;
- let brace_token = braced!(content in input);
- attr::parsing::parse_inner(&content, &mut attrs)?;
- let stmts = content.call(Block::parse_within)?;
-
- Ok(ExprWhile {
- attrs,
- label,
- while_token,
- cond: Box::new(cond),
- body: Block { brace_token, stmts },
- })
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprConst {
- fn parse(input: ParseStream) -> Result<Self> {
- let const_token: Token![const] = input.parse()?;
-
- let content;
- let brace_token = braced!(content in input);
- let inner_attrs = content.call(Attribute::parse_inner)?;
- let stmts = content.call(Block::parse_within)?;
-
- Ok(ExprConst {
- attrs: inner_attrs,
- const_token,
- block: Block { brace_token, stmts },
- })
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for Label {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(Label {
- name: input.parse()?,
- colon_token: input.parse()?,
- })
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for Option<Label> {
- fn parse(input: ParseStream) -> Result<Self> {
- if input.peek(Lifetime) {
- input.parse().map(Some)
- } else {
- Ok(None)
- }
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprContinue {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ExprContinue {
- attrs: Vec::new(),
- continue_token: input.parse()?,
- label: input.parse()?,
- })
- }
- }
-
- #[cfg(feature = "full")]
- fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
- let break_token: Token![break] = input.parse()?;
-
- let ahead = input.fork();
- let label: Option<Lifetime> = ahead.parse()?;
- if label.is_some() && ahead.peek(Token![:]) {
- // Not allowed: `break 'label: loop {...}`
- // Parentheses are required. `break ('label: loop {...})`
- let _ = ambiguous_expr(input, allow_struct)?;
- let start_span = label.unwrap().apostrophe;
- let end_span = input.cursor().prev_span();
- return Err(crate::error::new2(
- start_span,
- end_span,
- "parentheses required",
- ));
- }
-
- input.advance_to(&ahead);
- let expr = if can_begin_expr(input) && (allow_struct.0 || !input.peek(token::Brace)) {
- let expr = ambiguous_expr(input, allow_struct)?;
- Some(Box::new(expr))
- } else {
- None
- };
-
- Ok(ExprBreak {
- attrs: Vec::new(),
- break_token,
- label,
- expr,
- })
- }
-
- #[cfg(feature = "full")]
- fn expr_return(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn> {
- Ok(ExprReturn {
- attrs: Vec::new(),
- return_token: input.parse()?,
- expr: {
- if can_begin_expr(input) {
- // NOTE: return is greedy and eats blocks after it even when in a
- // position where structs are not allowed, such as in if statement
- // conditions. For example:
- //
- // if return { println!("A") } {} // Prints "A"
- let expr = ambiguous_expr(input, allow_struct)?;
- Some(Box::new(expr))
- } else {
- None
- }
- },
- })
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for FieldValue {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let member: Member = input.parse()?;
- let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() {
- let colon_token: Token![:] = input.parse()?;
- let value: Expr = input.parse()?;
- (Some(colon_token), value)
- } else if let Member::Named(ident) = &member {
- let value = Expr::Path(ExprPath {
- attrs: Vec::new(),
- qself: None,
- path: Path::from(ident.clone()),
- });
- (None, value)
- } else {
- unreachable!()
- };
-
- Ok(FieldValue {
- attrs,
- member,
- colon_token,
- expr: value,
- })
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprStruct {
- fn parse(input: ParseStream) -> Result<Self> {
- let (qself, path) = path::parsing::qpath(input, true)?;
- expr_struct_helper(input, qself, path)
- }
- }
-
- fn expr_struct_helper(
- input: ParseStream,
- qself: Option<QSelf>,
- path: Path,
- ) -> Result<ExprStruct> {
- let content;
- let brace_token = braced!(content in input);
-
- let mut fields = Punctuated::new();
- while !content.is_empty() {
- if content.peek(Token![..]) {
- return Ok(ExprStruct {
- attrs: Vec::new(),
- qself,
- path,
- brace_token,
- fields,
- dot2_token: Some(content.parse()?),
- rest: if content.is_empty() {
- None
- } else {
- Some(Box::new(content.parse()?))
- },
- });
- }
-
- fields.push(content.parse()?);
- if content.is_empty() {
- break;
- }
- let punct: Token![,] = content.parse()?;
- fields.push_punct(punct);
- }
-
- Ok(ExprStruct {
- attrs: Vec::new(),
- qself,
- path,
- brace_token,
- fields,
- dot2_token: None,
- rest: None,
- })
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprUnsafe {
- fn parse(input: ParseStream) -> Result<Self> {
- let unsafe_token: Token![unsafe] = input.parse()?;
-
- let content;
- let brace_token = braced!(content in input);
- let inner_attrs = content.call(Attribute::parse_inner)?;
- let stmts = content.call(Block::parse_within)?;
-
- Ok(ExprUnsafe {
- attrs: inner_attrs,
- unsafe_token,
- block: Block { brace_token, stmts },
- })
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprBlock {
- fn parse(input: ParseStream) -> Result<Self> {
- let mut attrs = input.call(Attribute::parse_outer)?;
- let label: Option<Label> = input.parse()?;
-
- let content;
- let brace_token = braced!(content in input);
- attr::parsing::parse_inner(&content, &mut attrs)?;
- let stmts = content.call(Block::parse_within)?;
-
- Ok(ExprBlock {
- attrs,
- label,
- block: Block { brace_token, stmts },
- })
- }
- }
-
- #[cfg(feature = "full")]
- fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
- let limits: RangeLimits = input.parse()?;
- let end = if matches!(limits, RangeLimits::HalfOpen(_))
- && (input.is_empty()
- || input.peek(Token![,])
- || input.peek(Token![;])
- || input.peek(Token![.]) && !input.peek(Token![..])
- || !allow_struct.0 && input.peek(token::Brace))
- {
- None
- } else {
- let to = ambiguous_expr(input, allow_struct)?;
- Some(Box::new(to))
- };
- Ok(ExprRange {
- attrs: Vec::new(),
- start: None,
- limits,
- end,
- })
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for RangeLimits {
- fn parse(input: ParseStream) -> Result<Self> {
- let lookahead = input.lookahead1();
- let dot_dot = lookahead.peek(Token![..]);
- let dot_dot_eq = dot_dot && lookahead.peek(Token![..=]);
- let dot_dot_dot = dot_dot && input.peek(Token![...]);
- if dot_dot_eq {
- input.parse().map(RangeLimits::Closed)
- } else if dot_dot && !dot_dot_dot {
- input.parse().map(RangeLimits::HalfOpen)
- } else {
- Err(lookahead.error())
- }
- }
- }
-
- #[cfg(feature = "full")]
- impl RangeLimits {
- pub(crate) fn parse_obsolete(input: ParseStream) -> Result<Self> {
- let lookahead = input.lookahead1();
- let dot_dot = lookahead.peek(Token![..]);
- let dot_dot_eq = dot_dot && lookahead.peek(Token![..=]);
- let dot_dot_dot = dot_dot && input.peek(Token![...]);
- if dot_dot_eq {
- input.parse().map(RangeLimits::Closed)
- } else if dot_dot_dot {
- let dot3: Token![...] = input.parse()?;
- Ok(RangeLimits::Closed(Token![..=](dot3.spans)))
- } else if dot_dot {
- input.parse().map(RangeLimits::HalfOpen)
- } else {
- Err(lookahead.error())
- }
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for ExprPath {
- fn parse(input: ParseStream) -> Result<Self> {
- #[cfg(not(feature = "full"))]
- let attrs = Vec::new();
- #[cfg(feature = "full")]
- let attrs = input.call(Attribute::parse_outer)?;
-
- let (qself, path) = path::parsing::qpath(input, true)?;
-
- Ok(ExprPath { attrs, qself, path })
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for Member {
- fn parse(input: ParseStream) -> Result<Self> {
- if input.peek(Ident) {
- input.parse().map(Member::Named)
- } else if input.peek(LitInt) {
- input.parse().map(Member::Unnamed)
- } else {
- Err(input.error("expected identifier or integer"))
- }
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for Arm {
- fn parse(input: ParseStream) -> Result<Arm> {
- let requires_comma;
- Ok(Arm {
- attrs: input.call(Attribute::parse_outer)?,
- pat: Pat::parse_multi_with_leading_vert(input)?,
- guard: {
- if input.peek(Token![if]) {
- let if_token: Token![if] = input.parse()?;
- let guard: Expr = input.parse()?;
- Some((if_token, Box::new(guard)))
- } else {
- None
- }
- },
- fat_arrow_token: input.parse()?,
- body: {
- let body = input.call(expr_early)?;
- requires_comma = requires_terminator(&body);
- Box::new(body)
- },
- comma: {
- if requires_comma && !input.is_empty() {
- Some(input.parse()?)
- } else {
- input.parse()?
- }
- },
- })
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for Index {
- fn parse(input: ParseStream) -> Result<Self> {
- let lit: LitInt = input.parse()?;
- if lit.suffix().is_empty() {
- Ok(Index {
- index: lit
- .base10_digits()
- .parse()
- .map_err(|err| Error::new(lit.span(), err))?,
- span: lit.span(),
- })
- } else {
- Err(Error::new(lit.span(), "expected unsuffixed integer"))
- }
- }
- }
-
- fn multi_index(e: &mut Expr, dot_token: &mut Token![.], float: LitFloat) -> Result<bool> {
- let float_token = float.token();
- let float_span = float_token.span();
- let mut float_repr = float_token.to_string();
- let trailing_dot = float_repr.ends_with('.');
- if trailing_dot {
- float_repr.truncate(float_repr.len() - 1);
- }
-
- let mut offset = 0;
- for part in float_repr.split('.') {
- let mut index: Index =
- crate::parse_str(part).map_err(|err| Error::new(float_span, err))?;
- let part_end = offset + part.len();
- index.span = float_token.subspan(offset..part_end).unwrap_or(float_span);
-
- let base = mem::replace(e, Expr::DUMMY);
- *e = Expr::Field(ExprField {
- attrs: Vec::new(),
- base: Box::new(base),
- dot_token: Token![.](dot_token.span),
- member: Member::Unnamed(index),
- });
-
- let dot_span = float_token
- .subspan(part_end..part_end + 1)
- .unwrap_or(float_span);
- *dot_token = Token![.](dot_span);
- offset = part_end + 1;
- }
-
- Ok(!trailing_dot)
- }
-
- impl Member {
- pub(crate) fn is_named(&self) -> bool {
- match self {
- Member::Named(_) => true,
- Member::Unnamed(_) => false,
- }
- }
- }
-
- fn check_cast(input: ParseStream) -> Result<()> {
- let kind = if input.peek(Token![.]) && !input.peek(Token![..]) {
- if input.peek2(Token![await]) {
- "`.await`"
- } else if input.peek2(Ident) && (input.peek3(token::Paren) || input.peek3(Token![::])) {
- "a method call"
- } else {
- "a field access"
- }
- } else if input.peek(Token![?]) {
- "`?`"
- } else if input.peek(token::Bracket) {
- "indexing"
- } else if input.peek(token::Paren) {
- "a function call"
- } else {
- return Ok(());
- };
- let msg = format!("casts cannot be followed by {}", kind);
- Err(input.error(msg))
- }
-}
-
-#[cfg(feature = "printing")]
-pub(crate) mod printing {
- use super::*;
- #[cfg(feature = "full")]
- use crate::attr::FilterAttrs;
- use proc_macro2::{Literal, TokenStream};
- use quote::{ToTokens, TokenStreamExt};
-
- // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
- // before appending it to `TokenStream`.
- #[cfg(feature = "full")]
- fn wrap_bare_struct(tokens: &mut TokenStream, e: &Expr) {
- if let Expr::Struct(_) = *e {
- token::Paren::default().surround(tokens, |tokens| {
- e.to_tokens(tokens);
- });
- } else {
- e.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- pub(crate) fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
- tokens.append_all(attrs.outer());
- }
-
- #[cfg(feature = "full")]
- fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
- tokens.append_all(attrs.inner());
- }
-
- #[cfg(not(feature = "full"))]
- pub(crate) fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprArray {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.bracket_token.surround(tokens, |tokens| {
- self.elems.to_tokens(tokens);
- });
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprAssign {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.left.to_tokens(tokens);
- self.eq_token.to_tokens(tokens);
- self.right.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprAsync {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.async_token.to_tokens(tokens);
- self.capture.to_tokens(tokens);
- self.block.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprAwait {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.base.to_tokens(tokens);
- self.dot_token.to_tokens(tokens);
- self.await_token.to_tokens(tokens);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprBinary {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.left.to_tokens(tokens);
- self.op.to_tokens(tokens);
- self.right.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprBlock {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.label.to_tokens(tokens);
- self.block.brace_token.surround(tokens, |tokens| {
- inner_attrs_to_tokens(&self.attrs, tokens);
- tokens.append_all(&self.block.stmts);
- });
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprBreak {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.break_token.to_tokens(tokens);
- self.label.to_tokens(tokens);
- self.expr.to_tokens(tokens);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprCall {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.func.to_tokens(tokens);
- self.paren_token.surround(tokens, |tokens| {
- self.args.to_tokens(tokens);
- });
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprCast {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.expr.to_tokens(tokens);
- self.as_token.to_tokens(tokens);
- self.ty.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprClosure {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.lifetimes.to_tokens(tokens);
- self.constness.to_tokens(tokens);
- self.movability.to_tokens(tokens);
- self.asyncness.to_tokens(tokens);
- self.capture.to_tokens(tokens);
- self.or1_token.to_tokens(tokens);
- self.inputs.to_tokens(tokens);
- self.or2_token.to_tokens(tokens);
- self.output.to_tokens(tokens);
- self.body.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprConst {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.const_token.to_tokens(tokens);
- self.block.brace_token.surround(tokens, |tokens| {
- inner_attrs_to_tokens(&self.attrs, tokens);
- tokens.append_all(&self.block.stmts);
- });
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprContinue {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.continue_token.to_tokens(tokens);
- self.label.to_tokens(tokens);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprField {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.base.to_tokens(tokens);
- self.dot_token.to_tokens(tokens);
- self.member.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprForLoop {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.label.to_tokens(tokens);
- self.for_token.to_tokens(tokens);
- self.pat.to_tokens(tokens);
- self.in_token.to_tokens(tokens);
- wrap_bare_struct(tokens, &self.expr);
- self.body.brace_token.surround(tokens, |tokens| {
- inner_attrs_to_tokens(&self.attrs, tokens);
- tokens.append_all(&self.body.stmts);
- });
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprGroup {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.group_token.surround(tokens, |tokens| {
- self.expr.to_tokens(tokens);
- });
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprIf {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.if_token.to_tokens(tokens);
- wrap_bare_struct(tokens, &self.cond);
- self.then_branch.to_tokens(tokens);
- if let Some((else_token, else_)) = &self.else_branch {
- else_token.to_tokens(tokens);
- // If we are not one of the valid expressions to exist in an else
- // clause, wrap ourselves in a block.
- match **else_ {
- Expr::If(_) | Expr::Block(_) => else_.to_tokens(tokens),
- _ => token::Brace::default().surround(tokens, |tokens| else_.to_tokens(tokens)),
- }
- }
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprIndex {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.expr.to_tokens(tokens);
- self.bracket_token.surround(tokens, |tokens| {
- self.index.to_tokens(tokens);
- });
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprInfer {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.underscore_token.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprLet {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.let_token.to_tokens(tokens);
- self.pat.to_tokens(tokens);
- self.eq_token.to_tokens(tokens);
- wrap_bare_struct(tokens, &self.expr);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprLit {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.lit.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprLoop {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.label.to_tokens(tokens);
- self.loop_token.to_tokens(tokens);
- self.body.brace_token.surround(tokens, |tokens| {
- inner_attrs_to_tokens(&self.attrs, tokens);
- tokens.append_all(&self.body.stmts);
- });
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprMacro {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.mac.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprMatch {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.match_token.to_tokens(tokens);
- wrap_bare_struct(tokens, &self.expr);
- self.brace_token.surround(tokens, |tokens| {
- inner_attrs_to_tokens(&self.attrs, tokens);
- for (i, arm) in self.arms.iter().enumerate() {
- arm.to_tokens(tokens);
- // Ensure that we have a comma after a non-block arm, except
- // for the last one.
- let is_last = i == self.arms.len() - 1;
- if !is_last && requires_terminator(&arm.body) && arm.comma.is_none() {
- <Token![,]>::default().to_tokens(tokens);
- }
- }
- });
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprMethodCall {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.receiver.to_tokens(tokens);
- self.dot_token.to_tokens(tokens);
- self.method.to_tokens(tokens);
- self.turbofish.to_tokens(tokens);
- self.paren_token.surround(tokens, |tokens| {
- self.args.to_tokens(tokens);
- });
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprParen {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.paren_token.surround(tokens, |tokens| {
- self.expr.to_tokens(tokens);
- });
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprPath {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- path::printing::print_path(tokens, &self.qself, &self.path);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprRange {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.start.to_tokens(tokens);
- self.limits.to_tokens(tokens);
- self.end.to_tokens(tokens);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprReference {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.and_token.to_tokens(tokens);
- self.mutability.to_tokens(tokens);
- self.expr.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprRepeat {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.bracket_token.surround(tokens, |tokens| {
- self.expr.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- self.len.to_tokens(tokens);
- });
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprReturn {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.return_token.to_tokens(tokens);
- self.expr.to_tokens(tokens);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprStruct {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- path::printing::print_path(tokens, &self.qself, &self.path);
- self.brace_token.surround(tokens, |tokens| {
- self.fields.to_tokens(tokens);
- if let Some(dot2_token) = &self.dot2_token {
- dot2_token.to_tokens(tokens);
- } else if self.rest.is_some() {
- Token![..](Span::call_site()).to_tokens(tokens);
- }
- self.rest.to_tokens(tokens);
- });
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprTry {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.expr.to_tokens(tokens);
- self.question_token.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprTryBlock {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.try_token.to_tokens(tokens);
- self.block.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprTuple {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.paren_token.surround(tokens, |tokens| {
- self.elems.to_tokens(tokens);
- // If we only have one argument, we need a trailing comma to
- // distinguish ExprTuple from ExprParen.
- if self.elems.len() == 1 && !self.elems.trailing_punct() {
- <Token![,]>::default().to_tokens(tokens);
- }
- });
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprUnary {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.op.to_tokens(tokens);
- self.expr.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprUnsafe {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.unsafe_token.to_tokens(tokens);
- self.block.brace_token.surround(tokens, |tokens| {
- inner_attrs_to_tokens(&self.attrs, tokens);
- tokens.append_all(&self.block.stmts);
- });
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprWhile {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.label.to_tokens(tokens);
- self.while_token.to_tokens(tokens);
- wrap_bare_struct(tokens, &self.cond);
- self.body.brace_token.surround(tokens, |tokens| {
- inner_attrs_to_tokens(&self.attrs, tokens);
- tokens.append_all(&self.body.stmts);
- });
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for ExprYield {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.yield_token.to_tokens(tokens);
- self.expr.to_tokens(tokens);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for Arm {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(&self.attrs);
- self.pat.to_tokens(tokens);
- if let Some((if_token, guard)) = &self.guard {
- if_token.to_tokens(tokens);
- guard.to_tokens(tokens);
- }
- self.fat_arrow_token.to_tokens(tokens);
- self.body.to_tokens(tokens);
- self.comma.to_tokens(tokens);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for FieldValue {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- outer_attrs_to_tokens(&self.attrs, tokens);
- self.member.to_tokens(tokens);
- if let Some(colon_token) = &self.colon_token {
- colon_token.to_tokens(tokens);
- self.expr.to_tokens(tokens);
- }
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for Index {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
- lit.set_span(self.span);
- tokens.append(lit);
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for Label {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- self.name.to_tokens(tokens);
- self.colon_token.to_tokens(tokens);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for Member {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- match self {
- Member::Named(ident) => ident.to_tokens(tokens),
- Member::Unnamed(index) => index.to_tokens(tokens),
- }
- }
- }
-
- #[cfg(feature = "full")]
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for RangeLimits {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- match self {
- RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
- RangeLimits::Closed(t) => t.to_tokens(tokens),
- }
- }
- }
-}