diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:39 +0000 |
commit | 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch) | |
tree | 3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /vendor/syn/src/expr.rs | |
parent | Releasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip |
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/syn/src/expr.rs')
-rw-r--r-- | vendor/syn/src/expr.rs | 1322 |
1 files changed, 549 insertions, 773 deletions
diff --git a/vendor/syn/src/expr.rs b/vendor/syn/src/expr.rs index 93a59b0e2..8caccb33f 100644 --- a/vendor/syn/src/expr.rs +++ b/vendor/syn/src/expr.rs @@ -1,7 +1,5 @@ use super::*; use crate::punctuated::Punctuated; -#[cfg(feature = "full")] -use crate::reserved::Reserved; use proc_macro2::{Span, TokenStream}; #[cfg(feature = "printing")] use quote::IdentFragment; @@ -87,7 +85,7 @@ ast_enum_of_structs! { /// 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"))))] - #[cfg_attr(not(syn_no_non_exhaustive), non_exhaustive)] + #[non_exhaustive] pub enum Expr { /// A slice literal expression: `[a, b, c, d]`. Array(ExprArray), @@ -95,24 +93,18 @@ ast_enum_of_structs! { /// An assignment expression: `a = compute()`. Assign(ExprAssign), - /// A compound assignment expression: `counter += 1`. - AssignOp(ExprAssignOp), - /// An async block: `async { ... }`. Async(ExprAsync), /// An await expression: `fut.await`. Await(ExprAwait), - /// A binary operation: `a + b`, `a * b`. + /// A binary operation: `a + b`, `a += b`. Binary(ExprBinary), /// A blocked scope: `{ ... }`. Block(ExprBlock), - /// A box expression: `box f`. - Box(ExprBox), - /// A `break`, with an optional label to break and an optional /// expression. Break(ExprBreak), @@ -126,6 +118,9 @@ ast_enum_of_structs! { /// A closure expression: `|a, b| a + b`. Closure(ExprClosure), + /// A const block: `const { ... }`. + Const(ExprConst), + /// A `continue`, with an optional label. Continue(ExprContinue), @@ -153,6 +148,9 @@ ast_enum_of_structs! { /// 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), @@ -207,9 +205,6 @@ ast_enum_of_structs! { /// A tuple expression: `(a, b, c, d)`. Tuple(ExprTuple), - /// A type ascription expression: `foo: f64`. - Type(ExprType), - /// A unary operation: `!x`, `*x`. Unary(ExprUnary), @@ -225,8 +220,6 @@ ast_enum_of_structs! { /// A yield expression: `yield expr`. Yield(ExprYield), - // Not public API. - // // For testing exhaustiveness in downstream code, use the following idiom: // // match expr { @@ -243,16 +236,11 @@ ast_enum_of_structs! { // 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. - #[cfg(syn_no_non_exhaustive)] - #[doc(hidden)] - __NonExhaustive, } } ast_struct! { /// A slice literal expression: `[a, b, c, d]`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprArray #full { pub attrs: Vec<Attribute>, @@ -263,8 +251,6 @@ ast_struct! { ast_struct! { /// An assignment expression: `a = compute()`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprAssign #full { pub attrs: Vec<Attribute>, @@ -275,22 +261,7 @@ ast_struct! { } ast_struct! { - /// A compound assignment expression: `counter += 1`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ExprAssignOp #full { - pub attrs: Vec<Attribute>, - pub left: Box<Expr>, - pub op: BinOp, - pub right: Box<Expr>, - } -} - -ast_struct! { /// An async block: `async { ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprAsync #full { pub attrs: Vec<Attribute>, @@ -302,22 +273,17 @@ ast_struct! { ast_struct! { /// An await expression: `fut.await`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[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, + pub await_token: Token![await], } } ast_struct! { - /// A binary operation: `a + b`, `a * b`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* + /// 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>, @@ -329,8 +295,6 @@ ast_struct! { ast_struct! { /// A blocked scope: `{ ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprBlock #full { pub attrs: Vec<Attribute>, @@ -340,22 +304,8 @@ ast_struct! { } ast_struct! { - /// A box expression: `box f`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ExprBox #full { - pub attrs: Vec<Attribute>, - pub box_token: Token![box], - pub expr: Box<Expr>, - } -} - -ast_struct! { /// A `break`, with an optional label to break and an optional /// expression. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprBreak #full { pub attrs: Vec<Attribute>, @@ -367,9 +317,6 @@ ast_struct! { ast_struct! { /// A function call expression: `invoke(a, b)`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct ExprCall { pub attrs: Vec<Attribute>, @@ -381,9 +328,6 @@ ast_struct! { ast_struct! { /// A cast expression: `foo as f64`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct ExprCast { pub attrs: Vec<Attribute>, @@ -395,11 +339,11 @@ ast_struct! { ast_struct! { /// A closure expression: `|a, b| a + b`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[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]>, @@ -412,9 +356,16 @@ ast_struct! { } ast_struct! { + /// A const block: `const { ... }`. + pub struct ExprConst #full { + pub attrs: Vec<Attribute>, + pub const_token: Token![const], + pub block: Block, + } +} + +ast_struct! { /// A `continue`, with an optional label. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprContinue #full { pub attrs: Vec<Attribute>, @@ -426,8 +377,6 @@ ast_struct! { ast_struct! { /// Access of a named struct field (`obj.k`) or unnamed tuple struct /// field (`obj.0`). - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct ExprField { pub attrs: Vec<Attribute>, @@ -439,14 +388,12 @@ ast_struct! { ast_struct! { /// A for loop: `for pat in expr { ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[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: Pat, + pub pat: Box<Pat>, pub in_token: Token![in], pub expr: Box<Expr>, pub body: Block, @@ -459,10 +406,8 @@ ast_struct! { /// This variant is important for faithfully representing the precedence /// of expressions and is related to `None`-delimited spans in a /// `TokenStream`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ExprGroup #full { + pub struct ExprGroup { pub attrs: Vec<Attribute>, pub group_token: token::Group, pub expr: Box<Expr>, @@ -475,8 +420,6 @@ ast_struct! { /// /// The `else` branch expression may only be an `If` or `Block` /// expression, not any of the other types of expression. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprIf #full { pub attrs: Vec<Attribute>, @@ -489,9 +432,6 @@ ast_struct! { ast_struct! { /// A square bracketed indexing expression: `vector[2]`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct ExprIndex { pub attrs: Vec<Attribute>, @@ -502,14 +442,20 @@ ast_struct! { } ast_struct! { + /// The inferred value of a const generic argument, denoted `_`. + pub struct ExprInfer #full { + pub attrs: Vec<Attribute>, + pub underscore_token: Token![_], + } +} + +ast_struct! { /// A `let` guard: `let Some(x) = opt`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprLet #full { pub attrs: Vec<Attribute>, pub let_token: Token![let], - pub pat: Pat, + pub pat: Box<Pat>, pub eq_token: Token![=], pub expr: Box<Expr>, } @@ -517,9 +463,6 @@ ast_struct! { ast_struct! { /// A literal in place of an expression: `1`, `"foo"`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct ExprLit { pub attrs: Vec<Attribute>, @@ -529,8 +472,6 @@ ast_struct! { ast_struct! { /// Conditionless loop: `loop { ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprLoop #full { pub attrs: Vec<Attribute>, @@ -542,10 +483,7 @@ ast_struct! { ast_struct! { /// A macro invocation expression: `format!("{}", q)`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ExprMacro #full { + pub struct ExprMacro { pub attrs: Vec<Attribute>, pub mac: Macro, } @@ -553,8 +491,6 @@ ast_struct! { ast_struct! { /// A `match` expression: `match n { Some(n) => {}, None => {} }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprMatch #full { pub attrs: Vec<Attribute>, @@ -567,15 +503,13 @@ ast_struct! { ast_struct! { /// A method call expression: `x.foo::<T>(a, b)`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprMethodCall #full { pub attrs: Vec<Attribute>, pub receiver: Box<Expr>, pub dot_token: Token![.], pub method: Ident, - pub turbofish: Option<MethodTurbofish>, + pub turbofish: Option<AngleBracketedGenericArguments>, pub paren_token: token::Paren, pub args: Punctuated<Expr, Token![,]>, } @@ -583,8 +517,6 @@ ast_struct! { ast_struct! { /// A parenthesized expression: `(a + b)`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct ExprParen { pub attrs: Vec<Attribute>, @@ -598,9 +530,6 @@ ast_struct! { /// parameters and a qualified self-type. /// /// A plain identifier like `x` is a path of length 1. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct ExprPath { pub attrs: Vec<Attribute>, @@ -611,26 +540,21 @@ ast_struct! { ast_struct! { /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprRange #full { pub attrs: Vec<Attribute>, - pub from: Option<Box<Expr>>, + pub start: Option<Box<Expr>>, pub limits: RangeLimits, - pub to: Option<Box<Expr>>, + pub end: Option<Box<Expr>>, } } ast_struct! { /// A referencing operation: `&a` or `&mut a`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprReference #full { pub attrs: Vec<Attribute>, pub and_token: Token![&], - pub raw: Reserved, pub mutability: Option<Token![mut]>, pub expr: Box<Expr>, } @@ -638,8 +562,6 @@ ast_struct! { ast_struct! { /// An array literal constructed from one repeated element: `[0u8; N]`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprRepeat #full { pub attrs: Vec<Attribute>, @@ -652,8 +574,6 @@ ast_struct! { ast_struct! { /// A `return`, with an optional value to be returned. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprReturn #full { pub attrs: Vec<Attribute>, @@ -667,11 +587,10 @@ ast_struct! { /// /// The `rest` provides the value of the remaining fields as in `S { a: /// 1, b: 1, ..rest }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprStruct #full { pub attrs: Vec<Attribute>, + pub qself: Option<QSelf>, pub path: Path, pub brace_token: token::Brace, pub fields: Punctuated<FieldValue, Token![,]>, @@ -682,8 +601,6 @@ ast_struct! { ast_struct! { /// A try-expression: `expr?`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprTry #full { pub attrs: Vec<Attribute>, @@ -694,8 +611,6 @@ ast_struct! { ast_struct! { /// A try block: `try { ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprTryBlock #full { pub attrs: Vec<Attribute>, @@ -706,8 +621,6 @@ ast_struct! { ast_struct! { /// A tuple expression: `(a, b, c, d)`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprTuple #full { pub attrs: Vec<Attribute>, @@ -717,23 +630,7 @@ ast_struct! { } ast_struct! { - /// A type ascription expression: `foo: f64`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ExprType #full { - pub attrs: Vec<Attribute>, - pub expr: Box<Expr>, - pub colon_token: Token![:], - pub ty: Box<Type>, - } -} - -ast_struct! { /// A unary operation: `!x`, `*x`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct ExprUnary { pub attrs: Vec<Attribute>, @@ -744,8 +641,6 @@ ast_struct! { ast_struct! { /// An unsafe block: `unsafe { ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprUnsafe #full { pub attrs: Vec<Attribute>, @@ -756,8 +651,6 @@ ast_struct! { ast_struct! { /// A while loop: `while expr { ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprWhile #full { pub attrs: Vec<Attribute>, @@ -770,8 +663,6 @@ ast_struct! { ast_struct! { /// A yield expression: `yield expr`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprYield #full { pub attrs: Vec<Attribute>, @@ -781,7 +672,7 @@ ast_struct! { } impl Expr { - #[cfg(all(feature = "parsing", not(syn_no_const_vec_new)))] + #[cfg(feature = "parsing")] const DUMMY: Self = Expr::Path(ExprPath { attrs: Vec::new(), qself: None, @@ -794,49 +685,45 @@ impl Expr { #[cfg(all(feature = "parsing", feature = "full"))] pub(crate) fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> { match self { - Expr::Box(ExprBox { attrs, .. }) - | Expr::Array(ExprArray { attrs, .. }) - | Expr::Call(ExprCall { attrs, .. }) - | Expr::MethodCall(ExprMethodCall { attrs, .. }) - | Expr::Tuple(ExprTuple { attrs, .. }) + Expr::Array(ExprArray { attrs, .. }) + | Expr::Assign(ExprAssign { attrs, .. }) + | Expr::Async(ExprAsync { attrs, .. }) + | Expr::Await(ExprAwait { attrs, .. }) | Expr::Binary(ExprBinary { attrs, .. }) - | Expr::Unary(ExprUnary { attrs, .. }) - | Expr::Lit(ExprLit { attrs, .. }) + | Expr::Block(ExprBlock { attrs, .. }) + | Expr::Break(ExprBreak { attrs, .. }) + | Expr::Call(ExprCall { attrs, .. }) | Expr::Cast(ExprCast { attrs, .. }) - | Expr::Type(ExprType { attrs, .. }) - | Expr::Let(ExprLet { attrs, .. }) - | Expr::If(ExprIf { attrs, .. }) - | Expr::While(ExprWhile { attrs, .. }) - | Expr::ForLoop(ExprForLoop { attrs, .. }) - | Expr::Loop(ExprLoop { attrs, .. }) - | Expr::Match(ExprMatch { attrs, .. }) | Expr::Closure(ExprClosure { attrs, .. }) - | Expr::Unsafe(ExprUnsafe { attrs, .. }) - | Expr::Block(ExprBlock { attrs, .. }) - | Expr::Assign(ExprAssign { attrs, .. }) - | Expr::AssignOp(ExprAssignOp { 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::Range(ExprRange { 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::Break(ExprBreak { attrs, .. }) - | Expr::Continue(ExprContinue { attrs, .. }) + | Expr::Repeat(ExprRepeat { attrs, .. }) | Expr::Return(ExprReturn { attrs, .. }) - | Expr::Macro(ExprMacro { attrs, .. }) | Expr::Struct(ExprStruct { attrs, .. }) - | Expr::Repeat(ExprRepeat { attrs, .. }) - | Expr::Paren(ExprParen { attrs, .. }) - | Expr::Group(ExprGroup { attrs, .. }) | Expr::Try(ExprTry { attrs, .. }) - | Expr::Async(ExprAsync { attrs, .. }) - | Expr::Await(ExprAwait { 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(), - - #[cfg(syn_no_non_exhaustive)] - _ => unreachable!(), } } } @@ -844,9 +731,6 @@ impl Expr { ast_enum! { /// A struct or tuple struct field accessed in a struct literal or field /// expression. - /// - /// *This type is available only if Syn is built with the `"derive"` or `"full"` - /// feature.* #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub enum Member { /// A named field like `self.x`. @@ -914,9 +798,6 @@ impl IdentFragment for Member { ast_struct! { /// The index of an unnamed tuple struct field. - /// - /// *This type is available only if Syn is built with the `"derive"` or `"full"` - /// feature.* #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct Index { pub index: u32, @@ -961,54 +842,16 @@ impl IdentFragment for Index { #[cfg(feature = "full")] ast_struct! { - /// The `::<>` explicit type parameters passed to a method call: - /// `parse::<u64>()`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct MethodTurbofish { - pub colon2_token: Token![::], - pub lt_token: Token![<], - pub args: Punctuated<GenericMethodArgument, Token![,]>, - pub gt_token: Token![>], - } -} - -#[cfg(feature = "full")] -ast_enum! { - /// An individual generic argument to a method, like `T`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub enum GenericMethodArgument { - /// A type argument. - Type(Type), - /// A const expression. Must be inside of a block. - /// - /// NOTE: Identity expressions are represented as Type arguments, as - /// they are indistinguishable syntactically. - Const(Expr), - } -} - -#[cfg(feature = "full")] -ast_struct! { /// A field-value pair in a struct literal. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct FieldValue { - /// Attributes tagged on the field. pub attrs: Vec<Attribute>, - - /// Name or index of the field. 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![:]>, - /// Value of the field. pub expr: Expr, } } @@ -1016,8 +859,6 @@ ast_struct! { #[cfg(feature = "full")] ast_struct! { /// A lifetime labeling a `for`, `while`, or `loop`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct Label { pub name: Lifetime, @@ -1027,7 +868,7 @@ ast_struct! { #[cfg(feature = "full")] ast_struct! { - /// One arm of a `match` expression: `0...10 => { return true; }`. + /// One arm of a `match` expression: `0..=10 => { return true; }`. /// /// As in: /// @@ -1035,7 +876,7 @@ ast_struct! { /// # fn f() -> bool { /// # let n = 0; /// match n { - /// 0...10 => { + /// 0..=10 => { /// return true; /// } /// // ... @@ -1044,8 +885,6 @@ ast_struct! { /// # false /// # } /// ``` - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct Arm { pub attrs: Vec<Attribute>, @@ -1060,8 +899,6 @@ ast_struct! { #[cfg(feature = "full")] ast_enum! { /// Limit types of a range, inclusive or exclusive. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub enum RangeLimits { /// Inclusive at the beginning, exclusive at the end. @@ -1074,30 +911,57 @@ ast_enum! { #[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/2679c38fc/src/librustc_ast/util/classify.rs#L7-L25 - match *expr { - Expr::Unsafe(..) - | Expr::Block(..) - | Expr::If(..) - | Expr::Match(..) - | Expr::While(..) - | Expr::Loop(..) - | Expr::ForLoop(..) - | Expr::Async(..) - | Expr::TryBlock(..) => false, - _ => true, + // 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")] pub(crate) mod parsing { use super::*; + use crate::parse::discouraged::Speculative; #[cfg(feature = "full")] use crate::parse::ParseBuffer; use crate::parse::{Parse, ParseStream, Result}; use crate::path; - #[cfg(feature = "full")] - use proc_macro2::TokenTree; use std::cmp::Ordering; crate::custom_keyword!(raw); @@ -1107,7 +971,8 @@ pub(crate) mod parsing { // // Struct literals are ambiguous in certain positions // https://github.com/rust-lang/rfcs/pull/92 - pub struct AllowStruct(bool); + #[cfg(feature = "full")] + pub(crate) struct AllowStruct(bool); enum Precedence { Any, @@ -1127,7 +992,7 @@ pub(crate) mod parsing { impl Precedence { fn of(op: &BinOp) -> Self { - match *op { + match op { BinOp::Add(_) | BinOp::Sub(_) => Precedence::Arithmetic, BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Term, BinOp::And(_) => Precedence::And, @@ -1142,16 +1007,16 @@ pub(crate) mod parsing { | BinOp::Ne(_) | BinOp::Ge(_) | BinOp::Gt(_) => Precedence::Compare, - BinOp::AddEq(_) - | BinOp::SubEq(_) - | BinOp::MulEq(_) - | BinOp::DivEq(_) - | BinOp::RemEq(_) - | BinOp::BitXorEq(_) - | BinOp::BitAndEq(_) - | BinOp::BitOrEq(_) - | BinOp::ShlEq(_) - | BinOp::ShrEq(_) => Precedence::Assign, + BinOp::AddAssign(_) + | BinOp::SubAssign(_) + | BinOp::MulAssign(_) + | BinOp::DivAssign(_) + | BinOp::RemAssign(_) + | BinOp::BitXorAssign(_) + | BinOp::BitAndAssign(_) + | BinOp::BitOrAssign(_) + | BinOp::ShlAssign(_) + | BinOp::ShrAssign(_) => Precedence::Assign, } } } @@ -1159,7 +1024,11 @@ pub(crate) mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for Expr { fn parse(input: ParseStream) -> Result<Self> { - ambiguous_expr(input, AllowStruct(true)) + ambiguous_expr( + input, + #[cfg(feature = "full")] + AllowStruct(true), + ) } } @@ -1251,8 +1120,10 @@ pub(crate) mod parsing { } } + #[cfg(feature = "full")] impl Copy for AllowStruct {} + #[cfg(feature = "full")] impl Clone for AllowStruct { fn clone(&self) -> Self { *self @@ -1289,13 +1160,12 @@ pub(crate) mod parsing { base: Precedence, ) -> Result<Expr> { loop { - if input - .fork() - .parse::<BinOp>() - .ok() - .map_or(false, |op| Precedence::of(&op) >= base) - { - let op: BinOp = input.parse()?; + 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 { @@ -1306,21 +1176,12 @@ pub(crate) mod parsing { break; } } - lhs = if precedence == Precedence::Assign { - Expr::AssignOp(ExprAssignOp { - attrs: Vec::new(), - left: Box::new(lhs), - op, - right: Box::new(rhs), - }) - } else { - Expr::Binary(ExprBinary { - attrs: Vec::new(), - left: Box::new(lhs), - op, - right: Box::new(rhs), - }) - }; + 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![==]) @@ -1344,11 +1205,12 @@ pub(crate) mod parsing { }); } else if Precedence::Range >= base && input.peek(Token![..]) { let limits: RangeLimits = input.parse()?; - let rhs = if input.is_empty() - || input.peek(Token![,]) - || input.peek(Token![;]) - || input.peek(Token![.]) && !input.peek(Token![..]) - || !allow_struct.0 && input.peek(token::Brace) + 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 { @@ -1365,9 +1227,9 @@ pub(crate) mod parsing { }; lhs = Expr::Range(ExprRange { attrs: Vec::new(), - from: Some(Box::new(lhs)), + start: Some(Box::new(lhs)), limits, - to: rhs.map(Box::new), + end: rhs.map(Box::new), }); } else if Precedence::Cast >= base && input.peek(Token![as]) { let as_token: Token![as] = input.parse()?; @@ -1381,18 +1243,6 @@ pub(crate) mod parsing { as_token, ty: Box::new(ty), }); - } else if Precedence::Cast >= base && input.peek(Token![:]) && !input.peek(Token![::]) { - let colon_token: Token![:] = 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::Type(ExprType { - attrs: Vec::new(), - expr: Box::new(lhs), - colon_token, - ty: Box::new(ty), - }); } else { break; } @@ -1401,26 +1251,20 @@ pub(crate) mod parsing { } #[cfg(not(feature = "full"))] - fn parse_expr( - input: ParseStream, - mut lhs: Expr, - allow_struct: AllowStruct, - base: Precedence, - ) -> Result<Expr> { + fn parse_expr(input: ParseStream, mut lhs: Expr, base: Precedence) -> Result<Expr> { loop { - if input - .fork() - .parse::<BinOp>() - .ok() - .map_or(false, |op| Precedence::of(&op) >= base) - { - let op: BinOp = input.parse()?; + 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)?; + 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, allow_struct, next)?; + rhs = parse_expr(input, rhs, next)?; } else { break; } @@ -1467,9 +1311,22 @@ pub(crate) mod parsing { } // Parse an arbitrary expression. - fn ambiguous_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> { - let lhs = unary_expr(input, allow_struct)?; - parse_expr(input, lhs, allow_struct, Precedence::Any) + 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")] @@ -1523,13 +1380,10 @@ pub(crate) mod parsing { Ok(Expr::Reference(ExprReference { attrs, and_token, - raw: Reserved::default(), mutability, expr, })) } - } else if input.peek(Token![box]) { - expr_box(input, attrs, allow_struct).map(Expr::Box) } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) { expr_unary(input, attrs, allow_struct).map(Expr::Unary) } else { @@ -1538,15 +1392,15 @@ pub(crate) mod parsing { } #[cfg(not(feature = "full"))] - fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> { + fn unary_expr(input: ParseStream) -> Result<Expr> { 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, allow_struct)?), + expr: Box::new(unary_expr(input)?), })) } else { - trailer_expr(input, allow_struct) + trailer_expr(input) } } @@ -1586,7 +1440,7 @@ pub(crate) mod parsing { attrs: Vec::new(), func: Box::new(e), paren_token: parenthesized!(content in input), - args: content.parse_terminated(Expr::parse)?, + args: content.parse_terminated(Expr::parse, Token![,])?, }); } else if input.peek(Token![.]) && !input.peek(Token![..]) @@ -1597,7 +1451,14 @@ pub(crate) mod parsing { { let mut dot_token: Token![.] = input.parse()?; - let await_token: Option<token::Await> = 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(), @@ -1608,16 +1469,9 @@ pub(crate) mod parsing { continue; } - 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![::]) { - Some(input.parse::<MethodTurbofish>()?) + Some(AngleBracketedGenericArguments::parse_turbofish(input)?) } else { None }; @@ -1632,7 +1486,7 @@ pub(crate) mod parsing { method, turbofish, paren_token: parenthesized!(content in input), - args: content.parse_terminated(Expr::parse)?, + args: content.parse_terminated(Expr::parse, Token![,])?, }); continue; } @@ -1666,8 +1520,8 @@ pub(crate) mod parsing { } #[cfg(not(feature = "full"))] - fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> { - let mut e = atom_expr(input, allow_struct)?; + fn trailer_expr(input: ParseStream) -> Result<Expr> { + let mut e = atom_expr(input)?; loop { if input.peek(token::Paren) { @@ -1676,9 +1530,11 @@ pub(crate) mod parsing { attrs: Vec::new(), func: Box::new(e), paren_token: parenthesized!(content in input), - args: content.parse_terminated(Expr::parse)?, + args: content.parse_terminated(Expr::parse, Token![,])?, }); - } else if input.peek(Token![.]) && !input.peek(Token![..]) && !input.peek2(token::Await) + } 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()?; @@ -1728,20 +1584,15 @@ pub(crate) mod parsing { } else if input.peek(Token![try]) && input.peek2(token::Brace) { input.parse().map(Expr::TryBlock) } else if input.peek(Token![|]) - || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move])) - || input.peek(Token![static]) || 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(Token![for]) - && input.peek2(Token![<]) - && (input.peek3(Lifetime) || input.peek3(Token![>])) - { - let begin = input.fork(); - input.parse::<BoundLifetimes>()?; - expr_closure(input, allow_struct)?; - let verbatim = verbatim::between(begin, input); - Ok(Expr::Verbatim(verbatim)) } else if input.peek(Ident) || input.peek(Token![::]) || input.peek(Token![<]) @@ -1749,6 +1600,7 @@ pub(crate) mod parsing { || 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) { @@ -1778,15 +1630,13 @@ pub(crate) mod parsing { } else if input.peek(Token![unsafe]) { input.parse().map(Expr::Unsafe) } else if input.peek(Token![const]) { - input.call(expr_const).map(Expr::Verbatim) + 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![_]) { - Ok(Expr::Verbatim(TokenStream::from( - input.parse::<TokenTree>()?, - ))) + input.parse().map(Expr::Infer) } else if input.peek(Lifetime) { let the_label: Label = input.parse()?; let mut expr = if input.peek(Token![while]) { @@ -1814,8 +1664,14 @@ pub(crate) mod parsing { } #[cfg(not(feature = "full"))] - fn atom_expr(input: ParseStream, _allow_struct: AllowStruct) -> Result<Expr> { - if input.peek(Lit) { + fn atom_expr(input: ParseStream) -> Result<Expr> { + if input.peek(token::Group) + && !input.peek2(Token![::]) + && !input.peek2(Token![!]) + && !input.peek2(token::Brace) + { + input.call(expr_group).map(Expr::Group) + } else if input.peek(Lit) { input.parse().map(Expr::Lit) } else if input.peek(token::Paren) { input.call(expr_paren).map(Expr::Paren) @@ -1827,56 +1683,50 @@ pub(crate) mod parsing { || input.peek(Token![super]) || input.peek(Token![crate]) { - input.parse().map(Expr::Path) + path_or_macro_or_struct(input) + } else if input.is_empty() { + Err(input.error("expected an expression")) } else { Err(input.error("unsupported expression; enable syn's features=[\"full\"]")) } } - #[cfg(feature = "full")] - fn path_or_macro_or_struct(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> { - let begin = input.fork(); - let expr: ExprPath = input.parse()?; - - if expr.qself.is_none() && input.peek(Token![!]) && !input.peek(Token![!=]) { - let mut contains_arguments = false; - for segment in &expr.path.segments { - match segment.arguments { - PathArguments::None => {} - PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => { - contains_arguments = true; - } - } - } + fn path_or_macro_or_struct( + input: ParseStream, + #[cfg(feature = "full")] allow_struct: AllowStruct, + ) -> Result<Expr> { + let (qself, path) = path::parsing::qpath(input, true)?; - if !contains_arguments { - let bang_token: Token![!] = input.parse()?; - let (delimiter, tokens) = mac::parse_delimiter(input)?; - return Ok(Expr::Macro(ExprMacro { - attrs: Vec::new(), - mac: Macro { - path: expr.path, - bang_token, - delimiter, - tokens, - }, - })); - } + 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(feature = "full")] if allow_struct.0 && input.peek(token::Brace) { - let expr_struct = expr_struct_helper(input, expr.path)?; - if expr.qself.is_some() { - Ok(Expr::Verbatim(verbatim::between(begin, input))) - } else { - Ok(Expr::Struct(expr_struct)) - } - } else { - Ok(Expr::Path(expr)) + return expr_struct_helper(input, qself, path).map(Expr::Struct); } + + Ok(Expr::Path(ExprPath { + attrs: Vec::new(), + qself, + path, + })) } - #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for ExprMacro { fn parse(input: ParseStream) -> Result<Self> { @@ -2031,8 +1881,8 @@ pub(crate) mod parsing { Expr::TryBlock(input.parse()?) } else if input.peek(Token![unsafe]) { Expr::Unsafe(input.parse()?) - } else if input.peek(Token![const]) { - Expr::Verbatim(input.call(expr_const)?) + } 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 { @@ -2070,7 +1920,6 @@ pub(crate) mod parsing { } } - #[cfg(feature = "full")] fn expr_group(input: ParseStream) -> Result<ExprGroup> { let group = crate::group::parse_group(input)?; Ok(ExprGroup { @@ -2099,58 +1948,12 @@ pub(crate) mod parsing { #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for GenericMethodArgument { - fn parse(input: ParseStream) -> Result<Self> { - if input.peek(Lit) { - let lit = input.parse()?; - return Ok(GenericMethodArgument::Const(Expr::Lit(lit))); - } - - if input.peek(token::Brace) { - let block: ExprBlock = input.parse()?; - return Ok(GenericMethodArgument::Const(Expr::Block(block))); - } - - input.parse().map(GenericMethodArgument::Type) - } - } - - #[cfg(feature = "full")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for MethodTurbofish { - fn parse(input: ParseStream) -> Result<Self> { - Ok(MethodTurbofish { - colon2_token: input.parse()?, - lt_token: input.parse()?, - args: { - let mut args = Punctuated::new(); - loop { - if input.peek(Token![>]) { - break; - } - let value: GenericMethodArgument = input.parse()?; - args.push_value(value); - if input.peek(Token![>]) { - break; - } - let punct = input.parse()?; - args.push_punct(punct); - } - args - }, - gt_token: input.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: pat::parsing::multi_pat_with_leading_vert(input)?, + pat: Box::new(Pat::parse_multi_with_leading_vert(input)?), eq_token: input.parse()?, expr: Box::new({ let allow_struct = AllowStruct(false); @@ -2204,13 +2007,24 @@ pub(crate) mod parsing { #[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::parsing::multi_pat_with_leading_vert(input)?; + 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)?; @@ -2224,7 +2038,7 @@ pub(crate) mod parsing { attrs, label, for_token, - pat, + pat: Box::new(pat), in_token, expr: Box::new(expr), body: Block { brace_token, stmts }, @@ -2308,7 +2122,6 @@ pub(crate) mod parsing { impl_by_parsing_expr! { ExprAssign, Assign, "expected assignment expression", - ExprAssignOp, AssignOp, "expected compound assignment expression", ExprAwait, Await, "expected await expression", ExprBinary, Binary, "expected binary operation", ExprCall, Call, "expected function call expression", @@ -2319,30 +2132,6 @@ pub(crate) mod parsing { ExprRange, Range, "expected range expression", ExprTry, Try, "expected try expression", ExprTuple, Tuple, "expected tuple expression", - ExprType, Type, "expected type ascription expression", - } - - #[cfg(feature = "full")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for ExprBox { - fn parse(input: ParseStream) -> Result<Self> { - let attrs = Vec::new(); - let allow_struct = AllowStruct(true); - expr_box(input, attrs, allow_struct) - } - } - - #[cfg(feature = "full")] - fn expr_box( - input: ParseStream, - attrs: Vec<Attribute>, - allow_struct: AllowStruct, - ) -> Result<ExprBox> { - Ok(ExprBox { - attrs, - box_token: input.parse()?, - expr: Box::new(unary_expr(input, allow_struct)?), - }) } #[cfg(feature = "full")] @@ -2385,7 +2174,6 @@ pub(crate) mod parsing { Ok(ExprReference { attrs: Vec::new(), and_token: input.parse()?, - raw: Reserved::default(), mutability: input.parse()?, expr: Box::new(unary_expr(input, allow_struct)?), }) @@ -2442,6 +2230,8 @@ pub(crate) mod parsing { #[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()?; @@ -2481,6 +2271,8 @@ pub(crate) mod parsing { Ok(ExprClosure { attrs: Vec::new(), + lifetimes, + constness, movability, asyncness, capture, @@ -2508,7 +2300,7 @@ pub(crate) mod parsing { #[cfg(feature = "full")] fn closure_arg(input: ParseStream) -> Result<Pat> { let attrs = input.call(Attribute::parse_outer)?; - let mut pat: Pat = input.parse()?; + let mut pat = Pat::parse_single(input)?; if input.peek(Token![:]) { Ok(Pat::Type(PatType { @@ -2519,11 +2311,12 @@ pub(crate) mod parsing { })) } else { match &mut pat { - Pat::Box(pat) => pat.attrs = attrs, + 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, @@ -2535,9 +2328,6 @@ pub(crate) mod parsing { Pat::Type(_) => unreachable!(), Pat::Verbatim(_) => {} Pat::Wild(pat) => pat.attrs = attrs, - - #[cfg(syn_no_non_exhaustive)] - _ => unreachable!(), } Ok(pat) } @@ -2569,6 +2359,25 @@ pub(crate) mod parsing { #[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 { @@ -2678,13 +2487,17 @@ pub(crate) mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for ExprStruct { fn parse(input: ParseStream) -> Result<Self> { - let path: Path = input.parse()?; - expr_struct_helper(input, path) + let (qself, path) = path::parsing::qpath(input, true)?; + expr_struct_helper(input, qself, path) } } #[cfg(feature = "full")] - fn expr_struct_helper(input: ParseStream, path: Path) -> Result<ExprStruct> { + fn expr_struct_helper( + input: ParseStream, + qself: Option<QSelf>, + path: Path, + ) -> Result<ExprStruct> { let content; let brace_token = braced!(content in input); @@ -2693,8 +2506,9 @@ pub(crate) mod parsing { if content.peek(Token![..]) { return Ok(ExprStruct { attrs: Vec::new(), - brace_token, + qself, path, + brace_token, fields, dot2_token: Some(content.parse()?), rest: if content.is_empty() { @@ -2715,8 +2529,9 @@ pub(crate) mod parsing { Ok(ExprStruct { attrs: Vec::new(), - brace_token, + qself, path, + brace_token, fields, dot2_token: None, rest: None, @@ -2743,19 +2558,6 @@ pub(crate) mod parsing { } #[cfg(feature = "full")] - pub(crate) fn expr_const(input: ParseStream) -> Result<TokenStream> { - let begin = input.fork(); - input.parse::<Token![const]>()?; - - let content; - braced!(content in input); - content.call(Attribute::parse_inner)?; - content.call(Block::parse_within)?; - - Ok(verbatim::between(begin, input)) - } - - #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for ExprBlock { fn parse(input: ParseStream) -> Result<Self> { @@ -2777,23 +2579,24 @@ pub(crate) mod parsing { #[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(), - from: None, - limits: input.parse()?, - to: { - if 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)) - } - }, + start: None, + limits, + end, }) } @@ -2802,12 +2605,32 @@ pub(crate) mod parsing { impl Parse for RangeLimits { fn parse(input: ParseStream) -> Result<Self> { let lookahead = input.lookahead1(); - if lookahead.peek(Token![..=]) { + 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 lookahead.peek(Token![...]) { + } else if dot_dot_dot { let dot3: Token![...] = input.parse()?; Ok(RangeLimits::Closed(Token![..=](dot3.spans))) - } else if lookahead.peek(Token![..]) { + } else if dot_dot { input.parse().map(RangeLimits::HalfOpen) } else { Err(lookahead.error()) @@ -2849,7 +2672,7 @@ pub(crate) mod parsing { let requires_comma; Ok(Arm { attrs: input.call(Attribute::parse_outer)?, - pat: pat::parsing::multi_pat_with_leading_vert(input)?, + pat: Pat::parse_multi_with_leading_vert(input)?, guard: { if input.peek(Token![if]) { let if_token: Token![if] = input.parse()?; @@ -2902,10 +2725,7 @@ pub(crate) mod parsing { } for part in float_repr.split('.') { let index = crate::parse_str(part).map_err(|err| Error::new(float.span(), err))?; - #[cfg(not(syn_no_const_vec_new))] let base = mem::replace(e, Expr::DUMMY); - #[cfg(syn_no_const_vec_new)] - let base = mem::replace(e, Expr::Verbatim(TokenStream::new())); *e = Expr::Field(ExprField { attrs: Vec::new(), base: Box::new(base), @@ -2920,7 +2740,7 @@ pub(crate) mod parsing { #[cfg(feature = "full")] impl Member { fn is_named(&self) -> bool { - match *self { + match self { Member::Named(_) => true, Member::Unnamed(_) => false, } @@ -2929,7 +2749,7 @@ pub(crate) mod parsing { fn check_cast(input: ParseStream) -> Result<()> { let kind = if input.peek(Token![.]) && !input.peek(Token![..]) { - if input.peek2(token::Await) { + if input.peek2(Token![await]) { "`.await`" } else if input.peek2(Ident) && (input.peek3(token::Paren) || input.peek3(Token![::])) { "a method call" @@ -2986,16 +2806,6 @@ pub(crate) mod printing { #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprBox { - fn to_tokens(&self, tokens: &mut TokenStream) { - outer_attrs_to_tokens(&self.attrs, tokens); - self.box_token.to_tokens(tokens); - self.expr.to_tokens(tokens); - } - } - - #[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); @@ -3005,94 +2815,81 @@ pub(crate) mod printing { } } + #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprCall { + impl ToTokens for ExprAssign { 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); - }); + 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 ExprMethodCall { + impl ToTokens for ExprAsync { 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); - }); + 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 MethodTurbofish { + impl ToTokens for ExprAwait { fn to_tokens(&self, tokens: &mut TokenStream) { - self.colon2_token.to_tokens(tokens); - self.lt_token.to_tokens(tokens); - self.args.to_tokens(tokens); - self.gt_token.to_tokens(tokens); + 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(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for GenericMethodArgument { + impl ToTokens for ExprBinary { fn to_tokens(&self, tokens: &mut TokenStream) { - match self { - GenericMethodArgument::Type(t) => t.to_tokens(tokens), - GenericMethodArgument::Const(c) => c.to_tokens(tokens), - } + 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 ExprTuple { + impl ToTokens for ExprBlock { 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); - } + 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 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_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprUnary { + impl ToTokens for ExprBreak { fn to_tokens(&self, tokens: &mut TokenStream) { outer_attrs_to_tokens(&self.attrs, tokens); - self.op.to_tokens(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 ExprLit { + impl ToTokens for ExprCall { fn to_tokens(&self, tokens: &mut TokenStream) { outer_attrs_to_tokens(&self.attrs, tokens); - self.lit.to_tokens(tokens); + self.func.to_tokens(tokens); + self.paren_token.surround(tokens, |tokens| { + self.args.to_tokens(tokens); + }); } } @@ -3108,71 +2905,52 @@ pub(crate) mod printing { #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprType { + impl ToTokens for ExprClosure { fn to_tokens(&self, tokens: &mut TokenStream) { outer_attrs_to_tokens(&self.attrs, tokens); - self.expr.to_tokens(tokens); - self.colon_token.to_tokens(tokens); - self.ty.to_tokens(tokens); - } - } - - #[cfg(feature = "full")] - fn maybe_wrap_else(tokens: &mut TokenStream, else_: &Option<(Token![else], Box<Expr>)>) { - if let Some((else_token, else_)) = else_ { - 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); - }); - } - } + 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 ExprLet { + impl ToTokens for ExprConst { 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); + 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 ExprIf { + impl ToTokens for ExprContinue { 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); - maybe_wrap_else(tokens, &self.else_branch); + self.continue_token.to_tokens(tokens); + self.label.to_tokens(tokens); } } - #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprWhile { + impl ToTokens for ExprField { 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); - }); + self.base.to_tokens(tokens); + self.dot_token.to_tokens(tokens); + self.member.to_tokens(tokens); } } @@ -3193,328 +2971,334 @@ pub(crate) mod printing { } } - #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprLoop { + impl ToTokens for ExprGroup { 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); + 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 ExprMatch { + impl ToTokens for ExprIf { 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); - } + 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(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprAsync { + impl ToTokens for ExprIndex { 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); + 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 ExprAwait { + impl ToTokens for ExprInfer { 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); + self.underscore_token.to_tokens(tokens); } } #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprTryBlock { + impl ToTokens for ExprLet { 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); + self.let_token.to_tokens(tokens); + self.pat.to_tokens(tokens); + self.eq_token.to_tokens(tokens); + wrap_bare_struct(tokens, &self.expr); } } - #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprYield { + impl ToTokens for ExprLit { 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); + self.lit.to_tokens(tokens); } } #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprClosure { + impl ToTokens for ExprLoop { fn to_tokens(&self, tokens: &mut TokenStream) { outer_attrs_to_tokens(&self.attrs, 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); + 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(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprUnsafe { + impl ToTokens for ExprMacro { 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); - }); + self.mac.to_tokens(tokens); } } #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprBlock { + impl ToTokens for ExprMatch { 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| { + 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); - tokens.append_all(&self.block.stmts); + 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(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprAssign { + impl ToTokens for ExprMethodCall { 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); + 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(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprAssignOp { + impl ToTokens for ExprParen { 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); + self.paren_token.surround(tokens, |tokens| { + self.expr.to_tokens(tokens); + }); } } #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprField { + impl ToTokens for ExprPath { 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_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), - } + path::printing::print_path(tokens, &self.qself, &self.path); } } + #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for Index { + impl ToTokens for ExprRange { 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); + outer_attrs_to_tokens(&self.attrs, tokens); + self.start.to_tokens(tokens); + self.limits.to_tokens(tokens); + self.end.to_tokens(tokens); } } + #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprIndex { + 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); - 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 RangeLimits { + impl ToTokens for ExprRepeat { fn to_tokens(&self, tokens: &mut TokenStream) { - match self { - RangeLimits::HalfOpen(t) => t.to_tokens(tokens), - RangeLimits::Closed(t) => t.to_tokens(tokens), - } + 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 ExprRange { + impl ToTokens for ExprReturn { fn to_tokens(&self, tokens: &mut TokenStream) { outer_attrs_to_tokens(&self.attrs, tokens); - self.from.to_tokens(tokens); - self.limits.to_tokens(tokens); - self.to.to_tokens(tokens); + self.return_token.to_tokens(tokens); + self.expr.to_tokens(tokens); } } + #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprPath { + 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 ExprReference { + impl ToTokens for ExprTry { 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); + self.question_token.to_tokens(tokens); } } #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprBreak { + impl ToTokens for ExprTryBlock { 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); + 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 ExprContinue { + impl ToTokens for ExprTuple { 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); + 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(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprReturn { + impl ToTokens for ExprUnary { fn to_tokens(&self, tokens: &mut TokenStream) { outer_attrs_to_tokens(&self.attrs, tokens); - self.return_token.to_tokens(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 ExprMacro { + impl ToTokens for ExprUnsafe { fn to_tokens(&self, tokens: &mut TokenStream) { outer_attrs_to_tokens(&self.attrs, tokens); - self.mac.to_tokens(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 ExprStruct { + impl ToTokens for ExprWhile { fn to_tokens(&self, tokens: &mut TokenStream) { outer_attrs_to_tokens(&self.attrs, tokens); - self.path.to_tokens(tokens); - 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); + 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 ExprRepeat { + impl ToTokens for ExprYield { 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); - }); + 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 ExprGroup { + impl ToTokens for Arm { 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); - }); + 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(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprParen { + impl ToTokens for FieldValue { fn to_tokens(&self, tokens: &mut TokenStream) { outer_attrs_to_tokens(&self.attrs, tokens); - self.paren_token.surround(tokens, |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(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ExprTry { + impl ToTokens for Index { 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); + let mut lit = Literal::i64_unsuffixed(i64::from(self.index)); + lit.set_span(self.span); + tokens.append(lit); } } @@ -3527,32 +3311,24 @@ pub(crate) mod printing { } } - #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for FieldValue { + impl ToTokens for Member { 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); + 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 Arm { + impl ToTokens for RangeLimits { 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); + match self { + RangeLimits::HalfOpen(t) => t.to_tokens(tokens), + RangeLimits::Closed(t) => t.to_tokens(tokens), } - self.fat_arrow_token.to_tokens(tokens); - self.body.to_tokens(tokens); - self.comma.to_tokens(tokens); } } } |