1*69942c0aSMiguel Ojeda // SPDX-License-Identifier: Apache-2.0 OR MIT 2*69942c0aSMiguel Ojeda 3808c999fSMiguel Ojeda use crate::attr::Attribute; 4808c999fSMiguel Ojeda #[cfg(all(feature = "parsing", feature = "full"))] 5808c999fSMiguel Ojeda use crate::error::Result; 6808c999fSMiguel Ojeda #[cfg(feature = "parsing")] 7808c999fSMiguel Ojeda use crate::ext::IdentExt as _; 8808c999fSMiguel Ojeda #[cfg(feature = "full")] 9808c999fSMiguel Ojeda use crate::generics::BoundLifetimes; 10808c999fSMiguel Ojeda use crate::ident::Ident; 11808c999fSMiguel Ojeda #[cfg(any(feature = "parsing", feature = "full"))] 12808c999fSMiguel Ojeda use crate::lifetime::Lifetime; 13808c999fSMiguel Ojeda use crate::lit::Lit; 14808c999fSMiguel Ojeda use crate::mac::Macro; 15808c999fSMiguel Ojeda use crate::op::{BinOp, UnOp}; 16808c999fSMiguel Ojeda #[cfg(feature = "parsing")] 17808c999fSMiguel Ojeda use crate::parse::ParseStream; 18808c999fSMiguel Ojeda #[cfg(feature = "full")] 19808c999fSMiguel Ojeda use crate::pat::Pat; 20808c999fSMiguel Ojeda use crate::path::{AngleBracketedGenericArguments, Path, QSelf}; 21808c999fSMiguel Ojeda use crate::punctuated::Punctuated; 22808c999fSMiguel Ojeda #[cfg(feature = "full")] 23808c999fSMiguel Ojeda use crate::stmt::Block; 24808c999fSMiguel Ojeda use crate::token; 25808c999fSMiguel Ojeda #[cfg(feature = "full")] 26808c999fSMiguel Ojeda use crate::ty::ReturnType; 27808c999fSMiguel Ojeda use crate::ty::Type; 28808c999fSMiguel Ojeda use proc_macro2::{Span, TokenStream}; 29808c999fSMiguel Ojeda #[cfg(feature = "printing")] 30808c999fSMiguel Ojeda use quote::IdentFragment; 31808c999fSMiguel Ojeda #[cfg(feature = "printing")] 32808c999fSMiguel Ojeda use std::fmt::{self, Display}; 33808c999fSMiguel Ojeda use std::hash::{Hash, Hasher}; 34808c999fSMiguel Ojeda #[cfg(all(feature = "parsing", feature = "full"))] 35808c999fSMiguel Ojeda use std::mem; 36808c999fSMiguel Ojeda 37808c999fSMiguel Ojeda ast_enum_of_structs! { 38808c999fSMiguel Ojeda /// A Rust expression. 39808c999fSMiguel Ojeda /// 40808c999fSMiguel Ojeda /// *This type is available only if Syn is built with the `"derive"` or `"full"` 41808c999fSMiguel Ojeda /// feature, but most of the variants are not available unless "full" is enabled.* 42808c999fSMiguel Ojeda /// 43808c999fSMiguel Ojeda /// # Syntax tree enums 44808c999fSMiguel Ojeda /// 45808c999fSMiguel Ojeda /// This type is a syntax tree enum. In Syn this and other syntax tree enums 46808c999fSMiguel Ojeda /// are designed to be traversed using the following rebinding idiom. 47808c999fSMiguel Ojeda /// 48808c999fSMiguel Ojeda /// ``` 49808c999fSMiguel Ojeda /// # use syn::Expr; 50808c999fSMiguel Ojeda /// # 51808c999fSMiguel Ojeda /// # fn example(expr: Expr) { 52808c999fSMiguel Ojeda /// # const IGNORE: &str = stringify! { 53808c999fSMiguel Ojeda /// let expr: Expr = /* ... */; 54808c999fSMiguel Ojeda /// # }; 55808c999fSMiguel Ojeda /// match expr { 56808c999fSMiguel Ojeda /// Expr::MethodCall(expr) => { 57808c999fSMiguel Ojeda /// /* ... */ 58808c999fSMiguel Ojeda /// } 59808c999fSMiguel Ojeda /// Expr::Cast(expr) => { 60808c999fSMiguel Ojeda /// /* ... */ 61808c999fSMiguel Ojeda /// } 62808c999fSMiguel Ojeda /// Expr::If(expr) => { 63808c999fSMiguel Ojeda /// /* ... */ 64808c999fSMiguel Ojeda /// } 65808c999fSMiguel Ojeda /// 66808c999fSMiguel Ojeda /// /* ... */ 67808c999fSMiguel Ojeda /// # _ => {} 68808c999fSMiguel Ojeda /// # } 69808c999fSMiguel Ojeda /// # } 70808c999fSMiguel Ojeda /// ``` 71808c999fSMiguel Ojeda /// 72808c999fSMiguel Ojeda /// We begin with a variable `expr` of type `Expr` that has no fields 73808c999fSMiguel Ojeda /// (because it is an enum), and by matching on it and rebinding a variable 74808c999fSMiguel Ojeda /// with the same name `expr` we effectively imbue our variable with all of 75808c999fSMiguel Ojeda /// the data fields provided by the variant that it turned out to be. So for 76808c999fSMiguel Ojeda /// example above if we ended up in the `MethodCall` case then we get to use 77808c999fSMiguel Ojeda /// `expr.receiver`, `expr.args` etc; if we ended up in the `If` case we get 78808c999fSMiguel Ojeda /// to use `expr.cond`, `expr.then_branch`, `expr.else_branch`. 79808c999fSMiguel Ojeda /// 80808c999fSMiguel Ojeda /// This approach avoids repeating the variant names twice on every line. 81808c999fSMiguel Ojeda /// 82808c999fSMiguel Ojeda /// ``` 83808c999fSMiguel Ojeda /// # use syn::{Expr, ExprMethodCall}; 84808c999fSMiguel Ojeda /// # 85808c999fSMiguel Ojeda /// # fn example(expr: Expr) { 86808c999fSMiguel Ojeda /// // Repetitive; recommend not doing this. 87808c999fSMiguel Ojeda /// match expr { 88808c999fSMiguel Ojeda /// Expr::MethodCall(ExprMethodCall { method, args, .. }) => { 89808c999fSMiguel Ojeda /// # } 90808c999fSMiguel Ojeda /// # _ => {} 91808c999fSMiguel Ojeda /// # } 92808c999fSMiguel Ojeda /// # } 93808c999fSMiguel Ojeda /// ``` 94808c999fSMiguel Ojeda /// 95808c999fSMiguel Ojeda /// In general, the name to which a syntax tree enum variant is bound should 96808c999fSMiguel Ojeda /// be a suitable name for the complete syntax tree enum type. 97808c999fSMiguel Ojeda /// 98808c999fSMiguel Ojeda /// ``` 99808c999fSMiguel Ojeda /// # use syn::{Expr, ExprField}; 100808c999fSMiguel Ojeda /// # 101808c999fSMiguel Ojeda /// # fn example(discriminant: ExprField) { 102808c999fSMiguel Ojeda /// // Binding is called `base` which is the name I would use if I were 103808c999fSMiguel Ojeda /// // assigning `*discriminant.base` without an `if let`. 104808c999fSMiguel Ojeda /// if let Expr::Tuple(base) = *discriminant.base { 105808c999fSMiguel Ojeda /// # } 106808c999fSMiguel Ojeda /// # } 107808c999fSMiguel Ojeda /// ``` 108808c999fSMiguel Ojeda /// 109808c999fSMiguel Ojeda /// A sign that you may not be choosing the right variable names is if you 110808c999fSMiguel Ojeda /// see names getting repeated in your code, like accessing 111808c999fSMiguel Ojeda /// `receiver.receiver` or `pat.pat` or `cond.cond`. 112808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 113808c999fSMiguel Ojeda #[non_exhaustive] 114808c999fSMiguel Ojeda pub enum Expr { 115808c999fSMiguel Ojeda /// A slice literal expression: `[a, b, c, d]`. 116808c999fSMiguel Ojeda Array(ExprArray), 117808c999fSMiguel Ojeda 118808c999fSMiguel Ojeda /// An assignment expression: `a = compute()`. 119808c999fSMiguel Ojeda Assign(ExprAssign), 120808c999fSMiguel Ojeda 121808c999fSMiguel Ojeda /// An async block: `async { ... }`. 122808c999fSMiguel Ojeda Async(ExprAsync), 123808c999fSMiguel Ojeda 124808c999fSMiguel Ojeda /// An await expression: `fut.await`. 125808c999fSMiguel Ojeda Await(ExprAwait), 126808c999fSMiguel Ojeda 127808c999fSMiguel Ojeda /// A binary operation: `a + b`, `a += b`. 128808c999fSMiguel Ojeda Binary(ExprBinary), 129808c999fSMiguel Ojeda 130808c999fSMiguel Ojeda /// A blocked scope: `{ ... }`. 131808c999fSMiguel Ojeda Block(ExprBlock), 132808c999fSMiguel Ojeda 133808c999fSMiguel Ojeda /// A `break`, with an optional label to break and an optional 134808c999fSMiguel Ojeda /// expression. 135808c999fSMiguel Ojeda Break(ExprBreak), 136808c999fSMiguel Ojeda 137808c999fSMiguel Ojeda /// A function call expression: `invoke(a, b)`. 138808c999fSMiguel Ojeda Call(ExprCall), 139808c999fSMiguel Ojeda 140808c999fSMiguel Ojeda /// A cast expression: `foo as f64`. 141808c999fSMiguel Ojeda Cast(ExprCast), 142808c999fSMiguel Ojeda 143808c999fSMiguel Ojeda /// A closure expression: `|a, b| a + b`. 144808c999fSMiguel Ojeda Closure(ExprClosure), 145808c999fSMiguel Ojeda 146808c999fSMiguel Ojeda /// A const block: `const { ... }`. 147808c999fSMiguel Ojeda Const(ExprConst), 148808c999fSMiguel Ojeda 149808c999fSMiguel Ojeda /// A `continue`, with an optional label. 150808c999fSMiguel Ojeda Continue(ExprContinue), 151808c999fSMiguel Ojeda 152808c999fSMiguel Ojeda /// Access of a named struct field (`obj.k`) or unnamed tuple struct 153808c999fSMiguel Ojeda /// field (`obj.0`). 154808c999fSMiguel Ojeda Field(ExprField), 155808c999fSMiguel Ojeda 156808c999fSMiguel Ojeda /// A for loop: `for pat in expr { ... }`. 157808c999fSMiguel Ojeda ForLoop(ExprForLoop), 158808c999fSMiguel Ojeda 159808c999fSMiguel Ojeda /// An expression contained within invisible delimiters. 160808c999fSMiguel Ojeda /// 161808c999fSMiguel Ojeda /// This variant is important for faithfully representing the precedence 162808c999fSMiguel Ojeda /// of expressions and is related to `None`-delimited spans in a 163808c999fSMiguel Ojeda /// `TokenStream`. 164808c999fSMiguel Ojeda Group(ExprGroup), 165808c999fSMiguel Ojeda 166808c999fSMiguel Ojeda /// An `if` expression with an optional `else` block: `if expr { ... } 167808c999fSMiguel Ojeda /// else { ... }`. 168808c999fSMiguel Ojeda /// 169808c999fSMiguel Ojeda /// The `else` branch expression may only be an `If` or `Block` 170808c999fSMiguel Ojeda /// expression, not any of the other types of expression. 171808c999fSMiguel Ojeda If(ExprIf), 172808c999fSMiguel Ojeda 173808c999fSMiguel Ojeda /// A square bracketed indexing expression: `vector[2]`. 174808c999fSMiguel Ojeda Index(ExprIndex), 175808c999fSMiguel Ojeda 176808c999fSMiguel Ojeda /// The inferred value of a const generic argument, denoted `_`. 177808c999fSMiguel Ojeda Infer(ExprInfer), 178808c999fSMiguel Ojeda 179808c999fSMiguel Ojeda /// A `let` guard: `let Some(x) = opt`. 180808c999fSMiguel Ojeda Let(ExprLet), 181808c999fSMiguel Ojeda 182808c999fSMiguel Ojeda /// A literal in place of an expression: `1`, `"foo"`. 183808c999fSMiguel Ojeda Lit(ExprLit), 184808c999fSMiguel Ojeda 185808c999fSMiguel Ojeda /// Conditionless loop: `loop { ... }`. 186808c999fSMiguel Ojeda Loop(ExprLoop), 187808c999fSMiguel Ojeda 188808c999fSMiguel Ojeda /// A macro invocation expression: `format!("{}", q)`. 189808c999fSMiguel Ojeda Macro(ExprMacro), 190808c999fSMiguel Ojeda 191808c999fSMiguel Ojeda /// A `match` expression: `match n { Some(n) => {}, None => {} }`. 192808c999fSMiguel Ojeda Match(ExprMatch), 193808c999fSMiguel Ojeda 194808c999fSMiguel Ojeda /// A method call expression: `x.foo::<T>(a, b)`. 195808c999fSMiguel Ojeda MethodCall(ExprMethodCall), 196808c999fSMiguel Ojeda 197808c999fSMiguel Ojeda /// A parenthesized expression: `(a + b)`. 198808c999fSMiguel Ojeda Paren(ExprParen), 199808c999fSMiguel Ojeda 200808c999fSMiguel Ojeda /// A path like `std::mem::replace` possibly containing generic 201808c999fSMiguel Ojeda /// parameters and a qualified self-type. 202808c999fSMiguel Ojeda /// 203808c999fSMiguel Ojeda /// A plain identifier like `x` is a path of length 1. 204808c999fSMiguel Ojeda Path(ExprPath), 205808c999fSMiguel Ojeda 206808c999fSMiguel Ojeda /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`. 207808c999fSMiguel Ojeda Range(ExprRange), 208808c999fSMiguel Ojeda 209808c999fSMiguel Ojeda /// Address-of operation: `&raw const place` or `&raw mut place`. 210808c999fSMiguel Ojeda RawAddr(ExprRawAddr), 211808c999fSMiguel Ojeda 212808c999fSMiguel Ojeda /// A referencing operation: `&a` or `&mut a`. 213808c999fSMiguel Ojeda Reference(ExprReference), 214808c999fSMiguel Ojeda 215808c999fSMiguel Ojeda /// An array literal constructed from one repeated element: `[0u8; N]`. 216808c999fSMiguel Ojeda Repeat(ExprRepeat), 217808c999fSMiguel Ojeda 218808c999fSMiguel Ojeda /// A `return`, with an optional value to be returned. 219808c999fSMiguel Ojeda Return(ExprReturn), 220808c999fSMiguel Ojeda 221808c999fSMiguel Ojeda /// A struct literal expression: `Point { x: 1, y: 1 }`. 222808c999fSMiguel Ojeda /// 223808c999fSMiguel Ojeda /// The `rest` provides the value of the remaining fields as in `S { a: 224808c999fSMiguel Ojeda /// 1, b: 1, ..rest }`. 225808c999fSMiguel Ojeda Struct(ExprStruct), 226808c999fSMiguel Ojeda 227808c999fSMiguel Ojeda /// A try-expression: `expr?`. 228808c999fSMiguel Ojeda Try(ExprTry), 229808c999fSMiguel Ojeda 230808c999fSMiguel Ojeda /// A try block: `try { ... }`. 231808c999fSMiguel Ojeda TryBlock(ExprTryBlock), 232808c999fSMiguel Ojeda 233808c999fSMiguel Ojeda /// A tuple expression: `(a, b, c, d)`. 234808c999fSMiguel Ojeda Tuple(ExprTuple), 235808c999fSMiguel Ojeda 236808c999fSMiguel Ojeda /// A unary operation: `!x`, `*x`. 237808c999fSMiguel Ojeda Unary(ExprUnary), 238808c999fSMiguel Ojeda 239808c999fSMiguel Ojeda /// An unsafe block: `unsafe { ... }`. 240808c999fSMiguel Ojeda Unsafe(ExprUnsafe), 241808c999fSMiguel Ojeda 242808c999fSMiguel Ojeda /// Tokens in expression position not interpreted by Syn. 243808c999fSMiguel Ojeda Verbatim(TokenStream), 244808c999fSMiguel Ojeda 245808c999fSMiguel Ojeda /// A while loop: `while expr { ... }`. 246808c999fSMiguel Ojeda While(ExprWhile), 247808c999fSMiguel Ojeda 248808c999fSMiguel Ojeda /// A yield expression: `yield expr`. 249808c999fSMiguel Ojeda Yield(ExprYield), 250808c999fSMiguel Ojeda 251808c999fSMiguel Ojeda // For testing exhaustiveness in downstream code, use the following idiom: 252808c999fSMiguel Ojeda // 253808c999fSMiguel Ojeda // match expr { 254808c999fSMiguel Ojeda // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))] 255808c999fSMiguel Ojeda // 256808c999fSMiguel Ojeda // Expr::Array(expr) => {...} 257808c999fSMiguel Ojeda // Expr::Assign(expr) => {...} 258808c999fSMiguel Ojeda // ... 259808c999fSMiguel Ojeda // Expr::Yield(expr) => {...} 260808c999fSMiguel Ojeda // 261808c999fSMiguel Ojeda // _ => { /* some sane fallback */ } 262808c999fSMiguel Ojeda // } 263808c999fSMiguel Ojeda // 264808c999fSMiguel Ojeda // This way we fail your tests but don't break your library when adding 265808c999fSMiguel Ojeda // a variant. You will be notified by a test failure when a variant is 266808c999fSMiguel Ojeda // added, so that you can add code to handle it, but your library will 267808c999fSMiguel Ojeda // continue to compile and work for downstream users in the interim. 268808c999fSMiguel Ojeda } 269808c999fSMiguel Ojeda } 270808c999fSMiguel Ojeda 271808c999fSMiguel Ojeda ast_struct! { 272808c999fSMiguel Ojeda /// A slice literal expression: `[a, b, c, d]`. 273808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 274808c999fSMiguel Ojeda pub struct ExprArray #full { 275808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 276808c999fSMiguel Ojeda pub bracket_token: token::Bracket, 277808c999fSMiguel Ojeda pub elems: Punctuated<Expr, Token![,]>, 278808c999fSMiguel Ojeda } 279808c999fSMiguel Ojeda } 280808c999fSMiguel Ojeda 281808c999fSMiguel Ojeda ast_struct! { 282808c999fSMiguel Ojeda /// An assignment expression: `a = compute()`. 283808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 284808c999fSMiguel Ojeda pub struct ExprAssign #full { 285808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 286808c999fSMiguel Ojeda pub left: Box<Expr>, 287808c999fSMiguel Ojeda pub eq_token: Token![=], 288808c999fSMiguel Ojeda pub right: Box<Expr>, 289808c999fSMiguel Ojeda } 290808c999fSMiguel Ojeda } 291808c999fSMiguel Ojeda 292808c999fSMiguel Ojeda ast_struct! { 293808c999fSMiguel Ojeda /// An async block: `async { ... }`. 294808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 295808c999fSMiguel Ojeda pub struct ExprAsync #full { 296808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 297808c999fSMiguel Ojeda pub async_token: Token![async], 298808c999fSMiguel Ojeda pub capture: Option<Token![move]>, 299808c999fSMiguel Ojeda pub block: Block, 300808c999fSMiguel Ojeda } 301808c999fSMiguel Ojeda } 302808c999fSMiguel Ojeda 303808c999fSMiguel Ojeda ast_struct! { 304808c999fSMiguel Ojeda /// An await expression: `fut.await`. 305808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 306808c999fSMiguel Ojeda pub struct ExprAwait #full { 307808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 308808c999fSMiguel Ojeda pub base: Box<Expr>, 309808c999fSMiguel Ojeda pub dot_token: Token![.], 310808c999fSMiguel Ojeda pub await_token: Token![await], 311808c999fSMiguel Ojeda } 312808c999fSMiguel Ojeda } 313808c999fSMiguel Ojeda 314808c999fSMiguel Ojeda ast_struct! { 315808c999fSMiguel Ojeda /// A binary operation: `a + b`, `a += b`. 316808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 317808c999fSMiguel Ojeda pub struct ExprBinary { 318808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 319808c999fSMiguel Ojeda pub left: Box<Expr>, 320808c999fSMiguel Ojeda pub op: BinOp, 321808c999fSMiguel Ojeda pub right: Box<Expr>, 322808c999fSMiguel Ojeda } 323808c999fSMiguel Ojeda } 324808c999fSMiguel Ojeda 325808c999fSMiguel Ojeda ast_struct! { 326808c999fSMiguel Ojeda /// A blocked scope: `{ ... }`. 327808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 328808c999fSMiguel Ojeda pub struct ExprBlock #full { 329808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 330808c999fSMiguel Ojeda pub label: Option<Label>, 331808c999fSMiguel Ojeda pub block: Block, 332808c999fSMiguel Ojeda } 333808c999fSMiguel Ojeda } 334808c999fSMiguel Ojeda 335808c999fSMiguel Ojeda ast_struct! { 336808c999fSMiguel Ojeda /// A `break`, with an optional label to break and an optional 337808c999fSMiguel Ojeda /// expression. 338808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 339808c999fSMiguel Ojeda pub struct ExprBreak #full { 340808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 341808c999fSMiguel Ojeda pub break_token: Token![break], 342808c999fSMiguel Ojeda pub label: Option<Lifetime>, 343808c999fSMiguel Ojeda pub expr: Option<Box<Expr>>, 344808c999fSMiguel Ojeda } 345808c999fSMiguel Ojeda } 346808c999fSMiguel Ojeda 347808c999fSMiguel Ojeda ast_struct! { 348808c999fSMiguel Ojeda /// A function call expression: `invoke(a, b)`. 349808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 350808c999fSMiguel Ojeda pub struct ExprCall { 351808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 352808c999fSMiguel Ojeda pub func: Box<Expr>, 353808c999fSMiguel Ojeda pub paren_token: token::Paren, 354808c999fSMiguel Ojeda pub args: Punctuated<Expr, Token![,]>, 355808c999fSMiguel Ojeda } 356808c999fSMiguel Ojeda } 357808c999fSMiguel Ojeda 358808c999fSMiguel Ojeda ast_struct! { 359808c999fSMiguel Ojeda /// A cast expression: `foo as f64`. 360808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 361808c999fSMiguel Ojeda pub struct ExprCast { 362808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 363808c999fSMiguel Ojeda pub expr: Box<Expr>, 364808c999fSMiguel Ojeda pub as_token: Token![as], 365808c999fSMiguel Ojeda pub ty: Box<Type>, 366808c999fSMiguel Ojeda } 367808c999fSMiguel Ojeda } 368808c999fSMiguel Ojeda 369808c999fSMiguel Ojeda ast_struct! { 370808c999fSMiguel Ojeda /// A closure expression: `|a, b| a + b`. 371808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 372808c999fSMiguel Ojeda pub struct ExprClosure #full { 373808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 374808c999fSMiguel Ojeda pub lifetimes: Option<BoundLifetimes>, 375808c999fSMiguel Ojeda pub constness: Option<Token![const]>, 376808c999fSMiguel Ojeda pub movability: Option<Token![static]>, 377808c999fSMiguel Ojeda pub asyncness: Option<Token![async]>, 378808c999fSMiguel Ojeda pub capture: Option<Token![move]>, 379808c999fSMiguel Ojeda pub or1_token: Token![|], 380808c999fSMiguel Ojeda pub inputs: Punctuated<Pat, Token![,]>, 381808c999fSMiguel Ojeda pub or2_token: Token![|], 382808c999fSMiguel Ojeda pub output: ReturnType, 383808c999fSMiguel Ojeda pub body: Box<Expr>, 384808c999fSMiguel Ojeda } 385808c999fSMiguel Ojeda } 386808c999fSMiguel Ojeda 387808c999fSMiguel Ojeda ast_struct! { 388808c999fSMiguel Ojeda /// A const block: `const { ... }`. 389808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 390808c999fSMiguel Ojeda pub struct ExprConst #full { 391808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 392808c999fSMiguel Ojeda pub const_token: Token![const], 393808c999fSMiguel Ojeda pub block: Block, 394808c999fSMiguel Ojeda } 395808c999fSMiguel Ojeda } 396808c999fSMiguel Ojeda 397808c999fSMiguel Ojeda ast_struct! { 398808c999fSMiguel Ojeda /// A `continue`, with an optional label. 399808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 400808c999fSMiguel Ojeda pub struct ExprContinue #full { 401808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 402808c999fSMiguel Ojeda pub continue_token: Token![continue], 403808c999fSMiguel Ojeda pub label: Option<Lifetime>, 404808c999fSMiguel Ojeda } 405808c999fSMiguel Ojeda } 406808c999fSMiguel Ojeda 407808c999fSMiguel Ojeda ast_struct! { 408808c999fSMiguel Ojeda /// Access of a named struct field (`obj.k`) or unnamed tuple struct 409808c999fSMiguel Ojeda /// field (`obj.0`). 410808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 411808c999fSMiguel Ojeda pub struct ExprField { 412808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 413808c999fSMiguel Ojeda pub base: Box<Expr>, 414808c999fSMiguel Ojeda pub dot_token: Token![.], 415808c999fSMiguel Ojeda pub member: Member, 416808c999fSMiguel Ojeda } 417808c999fSMiguel Ojeda } 418808c999fSMiguel Ojeda 419808c999fSMiguel Ojeda ast_struct! { 420808c999fSMiguel Ojeda /// A for loop: `for pat in expr { ... }`. 421808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 422808c999fSMiguel Ojeda pub struct ExprForLoop #full { 423808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 424808c999fSMiguel Ojeda pub label: Option<Label>, 425808c999fSMiguel Ojeda pub for_token: Token![for], 426808c999fSMiguel Ojeda pub pat: Box<Pat>, 427808c999fSMiguel Ojeda pub in_token: Token![in], 428808c999fSMiguel Ojeda pub expr: Box<Expr>, 429808c999fSMiguel Ojeda pub body: Block, 430808c999fSMiguel Ojeda } 431808c999fSMiguel Ojeda } 432808c999fSMiguel Ojeda 433808c999fSMiguel Ojeda ast_struct! { 434808c999fSMiguel Ojeda /// An expression contained within invisible delimiters. 435808c999fSMiguel Ojeda /// 436808c999fSMiguel Ojeda /// This variant is important for faithfully representing the precedence 437808c999fSMiguel Ojeda /// of expressions and is related to `None`-delimited spans in a 438808c999fSMiguel Ojeda /// `TokenStream`. 439808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 440808c999fSMiguel Ojeda pub struct ExprGroup { 441808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 442808c999fSMiguel Ojeda pub group_token: token::Group, 443808c999fSMiguel Ojeda pub expr: Box<Expr>, 444808c999fSMiguel Ojeda } 445808c999fSMiguel Ojeda } 446808c999fSMiguel Ojeda 447808c999fSMiguel Ojeda ast_struct! { 448808c999fSMiguel Ojeda /// An `if` expression with an optional `else` block: `if expr { ... } 449808c999fSMiguel Ojeda /// else { ... }`. 450808c999fSMiguel Ojeda /// 451808c999fSMiguel Ojeda /// The `else` branch expression may only be an `If` or `Block` 452808c999fSMiguel Ojeda /// expression, not any of the other types of expression. 453808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 454808c999fSMiguel Ojeda pub struct ExprIf #full { 455808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 456808c999fSMiguel Ojeda pub if_token: Token![if], 457808c999fSMiguel Ojeda pub cond: Box<Expr>, 458808c999fSMiguel Ojeda pub then_branch: Block, 459808c999fSMiguel Ojeda pub else_branch: Option<(Token![else], Box<Expr>)>, 460808c999fSMiguel Ojeda } 461808c999fSMiguel Ojeda } 462808c999fSMiguel Ojeda 463808c999fSMiguel Ojeda ast_struct! { 464808c999fSMiguel Ojeda /// A square bracketed indexing expression: `vector[2]`. 465808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 466808c999fSMiguel Ojeda pub struct ExprIndex { 467808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 468808c999fSMiguel Ojeda pub expr: Box<Expr>, 469808c999fSMiguel Ojeda pub bracket_token: token::Bracket, 470808c999fSMiguel Ojeda pub index: Box<Expr>, 471808c999fSMiguel Ojeda } 472808c999fSMiguel Ojeda } 473808c999fSMiguel Ojeda 474808c999fSMiguel Ojeda ast_struct! { 475808c999fSMiguel Ojeda /// The inferred value of a const generic argument, denoted `_`. 476808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 477808c999fSMiguel Ojeda pub struct ExprInfer #full { 478808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 479808c999fSMiguel Ojeda pub underscore_token: Token![_], 480808c999fSMiguel Ojeda } 481808c999fSMiguel Ojeda } 482808c999fSMiguel Ojeda 483808c999fSMiguel Ojeda ast_struct! { 484808c999fSMiguel Ojeda /// A `let` guard: `let Some(x) = opt`. 485808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 486808c999fSMiguel Ojeda pub struct ExprLet #full { 487808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 488808c999fSMiguel Ojeda pub let_token: Token![let], 489808c999fSMiguel Ojeda pub pat: Box<Pat>, 490808c999fSMiguel Ojeda pub eq_token: Token![=], 491808c999fSMiguel Ojeda pub expr: Box<Expr>, 492808c999fSMiguel Ojeda } 493808c999fSMiguel Ojeda } 494808c999fSMiguel Ojeda 495808c999fSMiguel Ojeda ast_struct! { 496808c999fSMiguel Ojeda /// A literal in place of an expression: `1`, `"foo"`. 497808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 498808c999fSMiguel Ojeda pub struct ExprLit { 499808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 500808c999fSMiguel Ojeda pub lit: Lit, 501808c999fSMiguel Ojeda } 502808c999fSMiguel Ojeda } 503808c999fSMiguel Ojeda 504808c999fSMiguel Ojeda ast_struct! { 505808c999fSMiguel Ojeda /// Conditionless loop: `loop { ... }`. 506808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 507808c999fSMiguel Ojeda pub struct ExprLoop #full { 508808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 509808c999fSMiguel Ojeda pub label: Option<Label>, 510808c999fSMiguel Ojeda pub loop_token: Token![loop], 511808c999fSMiguel Ojeda pub body: Block, 512808c999fSMiguel Ojeda } 513808c999fSMiguel Ojeda } 514808c999fSMiguel Ojeda 515808c999fSMiguel Ojeda ast_struct! { 516808c999fSMiguel Ojeda /// A macro invocation expression: `format!("{}", q)`. 517808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 518808c999fSMiguel Ojeda pub struct ExprMacro { 519808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 520808c999fSMiguel Ojeda pub mac: Macro, 521808c999fSMiguel Ojeda } 522808c999fSMiguel Ojeda } 523808c999fSMiguel Ojeda 524808c999fSMiguel Ojeda ast_struct! { 525808c999fSMiguel Ojeda /// A `match` expression: `match n { Some(n) => {}, None => {} }`. 526808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 527808c999fSMiguel Ojeda pub struct ExprMatch #full { 528808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 529808c999fSMiguel Ojeda pub match_token: Token![match], 530808c999fSMiguel Ojeda pub expr: Box<Expr>, 531808c999fSMiguel Ojeda pub brace_token: token::Brace, 532808c999fSMiguel Ojeda pub arms: Vec<Arm>, 533808c999fSMiguel Ojeda } 534808c999fSMiguel Ojeda } 535808c999fSMiguel Ojeda 536808c999fSMiguel Ojeda ast_struct! { 537808c999fSMiguel Ojeda /// A method call expression: `x.foo::<T>(a, b)`. 538808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 539808c999fSMiguel Ojeda pub struct ExprMethodCall { 540808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 541808c999fSMiguel Ojeda pub receiver: Box<Expr>, 542808c999fSMiguel Ojeda pub dot_token: Token![.], 543808c999fSMiguel Ojeda pub method: Ident, 544808c999fSMiguel Ojeda pub turbofish: Option<AngleBracketedGenericArguments>, 545808c999fSMiguel Ojeda pub paren_token: token::Paren, 546808c999fSMiguel Ojeda pub args: Punctuated<Expr, Token![,]>, 547808c999fSMiguel Ojeda } 548808c999fSMiguel Ojeda } 549808c999fSMiguel Ojeda 550808c999fSMiguel Ojeda ast_struct! { 551808c999fSMiguel Ojeda /// A parenthesized expression: `(a + b)`. 552808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 553808c999fSMiguel Ojeda pub struct ExprParen { 554808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 555808c999fSMiguel Ojeda pub paren_token: token::Paren, 556808c999fSMiguel Ojeda pub expr: Box<Expr>, 557808c999fSMiguel Ojeda } 558808c999fSMiguel Ojeda } 559808c999fSMiguel Ojeda 560808c999fSMiguel Ojeda ast_struct! { 561808c999fSMiguel Ojeda /// A path like `std::mem::replace` possibly containing generic 562808c999fSMiguel Ojeda /// parameters and a qualified self-type. 563808c999fSMiguel Ojeda /// 564808c999fSMiguel Ojeda /// A plain identifier like `x` is a path of length 1. 565808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 566808c999fSMiguel Ojeda pub struct ExprPath { 567808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 568808c999fSMiguel Ojeda pub qself: Option<QSelf>, 569808c999fSMiguel Ojeda pub path: Path, 570808c999fSMiguel Ojeda } 571808c999fSMiguel Ojeda } 572808c999fSMiguel Ojeda 573808c999fSMiguel Ojeda ast_struct! { 574808c999fSMiguel Ojeda /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`. 575808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 576808c999fSMiguel Ojeda pub struct ExprRange #full { 577808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 578808c999fSMiguel Ojeda pub start: Option<Box<Expr>>, 579808c999fSMiguel Ojeda pub limits: RangeLimits, 580808c999fSMiguel Ojeda pub end: Option<Box<Expr>>, 581808c999fSMiguel Ojeda } 582808c999fSMiguel Ojeda } 583808c999fSMiguel Ojeda 584808c999fSMiguel Ojeda ast_struct! { 585808c999fSMiguel Ojeda /// Address-of operation: `&raw const place` or `&raw mut place`. 586808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 587808c999fSMiguel Ojeda pub struct ExprRawAddr #full { 588808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 589808c999fSMiguel Ojeda pub and_token: Token![&], 590808c999fSMiguel Ojeda pub raw: Token![raw], 591808c999fSMiguel Ojeda pub mutability: PointerMutability, 592808c999fSMiguel Ojeda pub expr: Box<Expr>, 593808c999fSMiguel Ojeda } 594808c999fSMiguel Ojeda } 595808c999fSMiguel Ojeda 596808c999fSMiguel Ojeda ast_struct! { 597808c999fSMiguel Ojeda /// A referencing operation: `&a` or `&mut a`. 598808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 599808c999fSMiguel Ojeda pub struct ExprReference { 600808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 601808c999fSMiguel Ojeda pub and_token: Token![&], 602808c999fSMiguel Ojeda pub mutability: Option<Token![mut]>, 603808c999fSMiguel Ojeda pub expr: Box<Expr>, 604808c999fSMiguel Ojeda } 605808c999fSMiguel Ojeda } 606808c999fSMiguel Ojeda 607808c999fSMiguel Ojeda ast_struct! { 608808c999fSMiguel Ojeda /// An array literal constructed from one repeated element: `[0u8; N]`. 609808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 610808c999fSMiguel Ojeda pub struct ExprRepeat #full { 611808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 612808c999fSMiguel Ojeda pub bracket_token: token::Bracket, 613808c999fSMiguel Ojeda pub expr: Box<Expr>, 614808c999fSMiguel Ojeda pub semi_token: Token![;], 615808c999fSMiguel Ojeda pub len: Box<Expr>, 616808c999fSMiguel Ojeda } 617808c999fSMiguel Ojeda } 618808c999fSMiguel Ojeda 619808c999fSMiguel Ojeda ast_struct! { 620808c999fSMiguel Ojeda /// A `return`, with an optional value to be returned. 621808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 622808c999fSMiguel Ojeda pub struct ExprReturn #full { 623808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 624808c999fSMiguel Ojeda pub return_token: Token![return], 625808c999fSMiguel Ojeda pub expr: Option<Box<Expr>>, 626808c999fSMiguel Ojeda } 627808c999fSMiguel Ojeda } 628808c999fSMiguel Ojeda 629808c999fSMiguel Ojeda ast_struct! { 630808c999fSMiguel Ojeda /// A struct literal expression: `Point { x: 1, y: 1 }`. 631808c999fSMiguel Ojeda /// 632808c999fSMiguel Ojeda /// The `rest` provides the value of the remaining fields as in `S { a: 633808c999fSMiguel Ojeda /// 1, b: 1, ..rest }`. 634808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 635808c999fSMiguel Ojeda pub struct ExprStruct { 636808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 637808c999fSMiguel Ojeda pub qself: Option<QSelf>, 638808c999fSMiguel Ojeda pub path: Path, 639808c999fSMiguel Ojeda pub brace_token: token::Brace, 640808c999fSMiguel Ojeda pub fields: Punctuated<FieldValue, Token![,]>, 641808c999fSMiguel Ojeda pub dot2_token: Option<Token![..]>, 642808c999fSMiguel Ojeda pub rest: Option<Box<Expr>>, 643808c999fSMiguel Ojeda } 644808c999fSMiguel Ojeda } 645808c999fSMiguel Ojeda 646808c999fSMiguel Ojeda ast_struct! { 647808c999fSMiguel Ojeda /// A try-expression: `expr?`. 648808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 649808c999fSMiguel Ojeda pub struct ExprTry #full { 650808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 651808c999fSMiguel Ojeda pub expr: Box<Expr>, 652808c999fSMiguel Ojeda pub question_token: Token![?], 653808c999fSMiguel Ojeda } 654808c999fSMiguel Ojeda } 655808c999fSMiguel Ojeda 656808c999fSMiguel Ojeda ast_struct! { 657808c999fSMiguel Ojeda /// A try block: `try { ... }`. 658808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 659808c999fSMiguel Ojeda pub struct ExprTryBlock #full { 660808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 661808c999fSMiguel Ojeda pub try_token: Token![try], 662808c999fSMiguel Ojeda pub block: Block, 663808c999fSMiguel Ojeda } 664808c999fSMiguel Ojeda } 665808c999fSMiguel Ojeda 666808c999fSMiguel Ojeda ast_struct! { 667808c999fSMiguel Ojeda /// A tuple expression: `(a, b, c, d)`. 668808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 669808c999fSMiguel Ojeda pub struct ExprTuple { 670808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 671808c999fSMiguel Ojeda pub paren_token: token::Paren, 672808c999fSMiguel Ojeda pub elems: Punctuated<Expr, Token![,]>, 673808c999fSMiguel Ojeda } 674808c999fSMiguel Ojeda } 675808c999fSMiguel Ojeda 676808c999fSMiguel Ojeda ast_struct! { 677808c999fSMiguel Ojeda /// A unary operation: `!x`, `*x`. 678808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 679808c999fSMiguel Ojeda pub struct ExprUnary { 680808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 681808c999fSMiguel Ojeda pub op: UnOp, 682808c999fSMiguel Ojeda pub expr: Box<Expr>, 683808c999fSMiguel Ojeda } 684808c999fSMiguel Ojeda } 685808c999fSMiguel Ojeda 686808c999fSMiguel Ojeda ast_struct! { 687808c999fSMiguel Ojeda /// An unsafe block: `unsafe { ... }`. 688808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 689808c999fSMiguel Ojeda pub struct ExprUnsafe #full { 690808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 691808c999fSMiguel Ojeda pub unsafe_token: Token![unsafe], 692808c999fSMiguel Ojeda pub block: Block, 693808c999fSMiguel Ojeda } 694808c999fSMiguel Ojeda } 695808c999fSMiguel Ojeda 696808c999fSMiguel Ojeda ast_struct! { 697808c999fSMiguel Ojeda /// A while loop: `while expr { ... }`. 698808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 699808c999fSMiguel Ojeda pub struct ExprWhile #full { 700808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 701808c999fSMiguel Ojeda pub label: Option<Label>, 702808c999fSMiguel Ojeda pub while_token: Token![while], 703808c999fSMiguel Ojeda pub cond: Box<Expr>, 704808c999fSMiguel Ojeda pub body: Block, 705808c999fSMiguel Ojeda } 706808c999fSMiguel Ojeda } 707808c999fSMiguel Ojeda 708808c999fSMiguel Ojeda ast_struct! { 709808c999fSMiguel Ojeda /// A yield expression: `yield expr`. 710808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 711808c999fSMiguel Ojeda pub struct ExprYield #full { 712808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 713808c999fSMiguel Ojeda pub yield_token: Token![yield], 714808c999fSMiguel Ojeda pub expr: Option<Box<Expr>>, 715808c999fSMiguel Ojeda } 716808c999fSMiguel Ojeda } 717808c999fSMiguel Ojeda 718808c999fSMiguel Ojeda impl Expr { 719808c999fSMiguel Ojeda /// An unspecified invalid expression. 720808c999fSMiguel Ojeda /// 721808c999fSMiguel Ojeda /// ``` 722808c999fSMiguel Ojeda /// use quote::ToTokens; 723808c999fSMiguel Ojeda /// use std::mem; 724808c999fSMiguel Ojeda /// use syn::{parse_quote, Expr}; 725808c999fSMiguel Ojeda /// 726808c999fSMiguel Ojeda /// fn unparenthesize(e: &mut Expr) { 727808c999fSMiguel Ojeda /// while let Expr::Paren(paren) = e { 728808c999fSMiguel Ojeda /// *e = mem::replace(&mut *paren.expr, Expr::PLACEHOLDER); 729808c999fSMiguel Ojeda /// } 730808c999fSMiguel Ojeda /// } 731808c999fSMiguel Ojeda /// 732808c999fSMiguel Ojeda /// fn main() { 733808c999fSMiguel Ojeda /// let mut e: Expr = parse_quote! { ((1 + 1)) }; 734808c999fSMiguel Ojeda /// unparenthesize(&mut e); 735808c999fSMiguel Ojeda /// assert_eq!("1 + 1", e.to_token_stream().to_string()); 736808c999fSMiguel Ojeda /// } 737808c999fSMiguel Ojeda /// ``` 738808c999fSMiguel Ojeda pub const PLACEHOLDER: Self = Expr::Path(ExprPath { 739808c999fSMiguel Ojeda attrs: Vec::new(), 740808c999fSMiguel Ojeda qself: None, 741808c999fSMiguel Ojeda path: Path { 742808c999fSMiguel Ojeda leading_colon: None, 743808c999fSMiguel Ojeda segments: Punctuated::new(), 744808c999fSMiguel Ojeda }, 745808c999fSMiguel Ojeda }); 746808c999fSMiguel Ojeda 747808c999fSMiguel Ojeda /// An alternative to the primary `Expr::parse` parser (from the [`Parse`] 748808c999fSMiguel Ojeda /// trait) for ambiguous syntactic positions in which a trailing brace 749808c999fSMiguel Ojeda /// should not be taken as part of the expression. 750808c999fSMiguel Ojeda /// 751808c999fSMiguel Ojeda /// [`Parse`]: crate::parse::Parse 752808c999fSMiguel Ojeda /// 753808c999fSMiguel Ojeda /// Rust grammar has an ambiguity where braces sometimes turn a path 754808c999fSMiguel Ojeda /// expression into a struct initialization and sometimes do not. In the 755808c999fSMiguel Ojeda /// following code, the expression `S {}` is one expression. Presumably 756808c999fSMiguel Ojeda /// there is an empty struct `struct S {}` defined somewhere which it is 757808c999fSMiguel Ojeda /// instantiating. 758808c999fSMiguel Ojeda /// 759808c999fSMiguel Ojeda /// ``` 760808c999fSMiguel Ojeda /// # struct S; 761808c999fSMiguel Ojeda /// # impl std::ops::Deref for S { 762808c999fSMiguel Ojeda /// # type Target = bool; 763808c999fSMiguel Ojeda /// # fn deref(&self) -> &Self::Target { 764808c999fSMiguel Ojeda /// # &true 765808c999fSMiguel Ojeda /// # } 766808c999fSMiguel Ojeda /// # } 767808c999fSMiguel Ojeda /// let _ = *S {}; 768808c999fSMiguel Ojeda /// 769808c999fSMiguel Ojeda /// // parsed by rustc as: `*(S {})` 770808c999fSMiguel Ojeda /// ``` 771808c999fSMiguel Ojeda /// 772808c999fSMiguel Ojeda /// We would want to parse the above using `Expr::parse` after the `=` 773808c999fSMiguel Ojeda /// token. 774808c999fSMiguel Ojeda /// 775808c999fSMiguel Ojeda /// But in the following, `S {}` is *not* a struct init expression. 776808c999fSMiguel Ojeda /// 777808c999fSMiguel Ojeda /// ``` 778808c999fSMiguel Ojeda /// # const S: &bool = &true; 779808c999fSMiguel Ojeda /// if *S {} {} 780808c999fSMiguel Ojeda /// 781808c999fSMiguel Ojeda /// // parsed by rustc as: 782808c999fSMiguel Ojeda /// // 783808c999fSMiguel Ojeda /// // if (*S) { 784808c999fSMiguel Ojeda /// // /* empty block */ 785808c999fSMiguel Ojeda /// // } 786808c999fSMiguel Ojeda /// // { 787808c999fSMiguel Ojeda /// // /* another empty block */ 788808c999fSMiguel Ojeda /// // } 789808c999fSMiguel Ojeda /// ``` 790808c999fSMiguel Ojeda /// 791808c999fSMiguel Ojeda /// For that reason we would want to parse if-conditions using 792808c999fSMiguel Ojeda /// `Expr::parse_without_eager_brace` after the `if` token. Same for similar 793808c999fSMiguel Ojeda /// syntactic positions such as the condition expr after a `while` token or 794808c999fSMiguel Ojeda /// the expr at the top of a `match`. 795808c999fSMiguel Ojeda /// 796808c999fSMiguel Ojeda /// The Rust grammar's choices around which way this ambiguity is resolved 797808c999fSMiguel Ojeda /// at various syntactic positions is fairly arbitrary. Really either parse 798808c999fSMiguel Ojeda /// behavior could work in most positions, and language designers just 799808c999fSMiguel Ojeda /// decide each case based on which is more likely to be what the programmer 800808c999fSMiguel Ojeda /// had in mind most of the time. 801808c999fSMiguel Ojeda /// 802808c999fSMiguel Ojeda /// ``` 803808c999fSMiguel Ojeda /// # struct S; 804808c999fSMiguel Ojeda /// # fn doc() -> S { 805808c999fSMiguel Ojeda /// if return S {} {} 806808c999fSMiguel Ojeda /// # unreachable!() 807808c999fSMiguel Ojeda /// # } 808808c999fSMiguel Ojeda /// 809808c999fSMiguel Ojeda /// // parsed by rustc as: 810808c999fSMiguel Ojeda /// // 811808c999fSMiguel Ojeda /// // if (return (S {})) { 812808c999fSMiguel Ojeda /// // } 813808c999fSMiguel Ojeda /// // 814808c999fSMiguel Ojeda /// // but could equally well have been this other arbitrary choice: 815808c999fSMiguel Ojeda /// // 816808c999fSMiguel Ojeda /// // if (return S) { 817808c999fSMiguel Ojeda /// // } 818808c999fSMiguel Ojeda /// // {} 819808c999fSMiguel Ojeda /// ``` 820808c999fSMiguel Ojeda /// 821808c999fSMiguel Ojeda /// Note the grammar ambiguity on trailing braces is distinct from 822808c999fSMiguel Ojeda /// precedence and is not captured by assigning a precedence level to the 823808c999fSMiguel Ojeda /// braced struct init expr in relation to other operators. This can be 824808c999fSMiguel Ojeda /// illustrated by `return 0..S {}` vs `match 0..S {}`. The former parses as 825808c999fSMiguel Ojeda /// `return (0..(S {}))` implying tighter precedence for struct init than 826808c999fSMiguel Ojeda /// `..`, while the latter parses as `match (0..S) {}` implying tighter 827808c999fSMiguel Ojeda /// precedence for `..` than struct init, a contradiction. 828808c999fSMiguel Ojeda #[cfg(all(feature = "full", feature = "parsing"))] 829808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(all(feature = "full", feature = "parsing"))))] parse_without_eager_brace(input: ParseStream) -> Result<Expr>830808c999fSMiguel Ojeda pub fn parse_without_eager_brace(input: ParseStream) -> Result<Expr> { 831808c999fSMiguel Ojeda parsing::ambiguous_expr(input, parsing::AllowStruct(false)) 832808c999fSMiguel Ojeda } 833808c999fSMiguel Ojeda 834808c999fSMiguel Ojeda /// An alternative to the primary `Expr::parse` parser (from the [`Parse`] 835808c999fSMiguel Ojeda /// trait) for syntactic positions in which expression boundaries are placed 836808c999fSMiguel Ojeda /// more eagerly than done by the typical expression grammar. This includes 837808c999fSMiguel Ojeda /// expressions at the head of a statement or in the right-hand side of a 838808c999fSMiguel Ojeda /// `match` arm. 839808c999fSMiguel Ojeda /// 840808c999fSMiguel Ojeda /// [`Parse`]: crate::parse::Parse 841808c999fSMiguel Ojeda /// 842808c999fSMiguel Ojeda /// Compare the following cases: 843808c999fSMiguel Ojeda /// 844808c999fSMiguel Ojeda /// 1. 845808c999fSMiguel Ojeda /// ``` 846808c999fSMiguel Ojeda /// # let result = (); 847808c999fSMiguel Ojeda /// # let guard = false; 848808c999fSMiguel Ojeda /// # let cond = true; 849808c999fSMiguel Ojeda /// # let f = true; 850808c999fSMiguel Ojeda /// # let g = f; 851808c999fSMiguel Ojeda /// # 852808c999fSMiguel Ojeda /// let _ = match result { 853808c999fSMiguel Ojeda /// () if guard => if cond { f } else { g } 854808c999fSMiguel Ojeda /// () => false, 855808c999fSMiguel Ojeda /// }; 856808c999fSMiguel Ojeda /// ``` 857808c999fSMiguel Ojeda /// 858808c999fSMiguel Ojeda /// 2. 859808c999fSMiguel Ojeda /// ``` 860808c999fSMiguel Ojeda /// # let cond = true; 861808c999fSMiguel Ojeda /// # let f = (); 862808c999fSMiguel Ojeda /// # let g = f; 863808c999fSMiguel Ojeda /// # 864808c999fSMiguel Ojeda /// let _ = || { 865808c999fSMiguel Ojeda /// if cond { f } else { g } 866808c999fSMiguel Ojeda /// () 867808c999fSMiguel Ojeda /// }; 868808c999fSMiguel Ojeda /// ``` 869808c999fSMiguel Ojeda /// 870808c999fSMiguel Ojeda /// 3. 871808c999fSMiguel Ojeda /// ``` 872808c999fSMiguel Ojeda /// # let cond = true; 873808c999fSMiguel Ojeda /// # let f = || (); 874808c999fSMiguel Ojeda /// # let g = f; 875808c999fSMiguel Ojeda /// # 876808c999fSMiguel Ojeda /// let _ = [if cond { f } else { g } ()]; 877808c999fSMiguel Ojeda /// ``` 878808c999fSMiguel Ojeda /// 879808c999fSMiguel Ojeda /// The same sequence of tokens `if cond { f } else { g } ()` appears in 880808c999fSMiguel Ojeda /// expression position 3 times. The first two syntactic positions use eager 881808c999fSMiguel Ojeda /// placement of expression boundaries, and parse as `Expr::If`, with the 882808c999fSMiguel Ojeda /// adjacent `()` becoming `Pat::Tuple` or `Expr::Tuple`. In contrast, the 883808c999fSMiguel Ojeda /// third case uses standard expression boundaries and parses as 884808c999fSMiguel Ojeda /// `Expr::Call`. 885808c999fSMiguel Ojeda /// 886808c999fSMiguel Ojeda /// As with [`parse_without_eager_brace`], this ambiguity in the Rust 887808c999fSMiguel Ojeda /// grammar is independent of precedence. 888808c999fSMiguel Ojeda /// 889808c999fSMiguel Ojeda /// [`parse_without_eager_brace`]: Self::parse_without_eager_brace 890808c999fSMiguel Ojeda #[cfg(all(feature = "full", feature = "parsing"))] 891808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(all(feature = "full", feature = "parsing"))))] parse_with_earlier_boundary_rule(input: ParseStream) -> Result<Expr>892808c999fSMiguel Ojeda pub fn parse_with_earlier_boundary_rule(input: ParseStream) -> Result<Expr> { 893808c999fSMiguel Ojeda parsing::parse_with_earlier_boundary_rule(input) 894808c999fSMiguel Ojeda } 895808c999fSMiguel Ojeda 896808c999fSMiguel Ojeda /// Returns whether the next token in the parse stream is one that might 897808c999fSMiguel Ojeda /// possibly form the beginning of an expr. 898808c999fSMiguel Ojeda /// 899808c999fSMiguel Ojeda /// This classification is a load-bearing part of the grammar of some Rust 900808c999fSMiguel Ojeda /// expressions, notably `return` and `break`. For example `return < …` will 901808c999fSMiguel Ojeda /// never parse `<` as a binary operator regardless of what comes after, 902808c999fSMiguel Ojeda /// because `<` is a legal starting token for an expression and so it's 903808c999fSMiguel Ojeda /// required to be continued as a return value, such as `return <Struct as 904808c999fSMiguel Ojeda /// Trait>::CONST`. Meanwhile `return > …` treats the `>` as a binary 905808c999fSMiguel Ojeda /// operator because it cannot be a starting token for any Rust expression. 906808c999fSMiguel Ojeda #[cfg(feature = "parsing")] 907808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] peek(input: ParseStream) -> bool908808c999fSMiguel Ojeda pub fn peek(input: ParseStream) -> bool { 909808c999fSMiguel Ojeda input.peek(Ident::peek_any) && !input.peek(Token![as]) // value name or keyword 910808c999fSMiguel Ojeda || input.peek(token::Paren) // tuple 911808c999fSMiguel Ojeda || input.peek(token::Bracket) // array 912808c999fSMiguel Ojeda || input.peek(token::Brace) // block 913808c999fSMiguel Ojeda || input.peek(Lit) // literal 914808c999fSMiguel Ojeda || input.peek(Token![!]) && !input.peek(Token![!=]) // operator not 915808c999fSMiguel Ojeda || input.peek(Token![-]) && !input.peek(Token![-=]) && !input.peek(Token![->]) // unary minus 916808c999fSMiguel Ojeda || input.peek(Token![*]) && !input.peek(Token![*=]) // dereference 917808c999fSMiguel Ojeda || input.peek(Token![|]) && !input.peek(Token![|=]) // closure 918808c999fSMiguel Ojeda || input.peek(Token![&]) && !input.peek(Token![&=]) // reference 919808c999fSMiguel Ojeda || input.peek(Token![..]) // range 920808c999fSMiguel Ojeda || input.peek(Token![<]) && !input.peek(Token![<=]) && !input.peek(Token![<<=]) // associated path 921808c999fSMiguel Ojeda || input.peek(Token![::]) // absolute path 922808c999fSMiguel Ojeda || input.peek(Lifetime) // labeled loop 923808c999fSMiguel Ojeda || input.peek(Token![#]) // expression attributes 924808c999fSMiguel Ojeda } 925808c999fSMiguel Ojeda 926808c999fSMiguel Ojeda #[cfg(all(feature = "parsing", feature = "full"))] replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute>927808c999fSMiguel Ojeda pub(crate) fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> { 928808c999fSMiguel Ojeda match self { 929808c999fSMiguel Ojeda Expr::Array(ExprArray { attrs, .. }) 930808c999fSMiguel Ojeda | Expr::Assign(ExprAssign { attrs, .. }) 931808c999fSMiguel Ojeda | Expr::Async(ExprAsync { attrs, .. }) 932808c999fSMiguel Ojeda | Expr::Await(ExprAwait { attrs, .. }) 933808c999fSMiguel Ojeda | Expr::Binary(ExprBinary { attrs, .. }) 934808c999fSMiguel Ojeda | Expr::Block(ExprBlock { attrs, .. }) 935808c999fSMiguel Ojeda | Expr::Break(ExprBreak { attrs, .. }) 936808c999fSMiguel Ojeda | Expr::Call(ExprCall { attrs, .. }) 937808c999fSMiguel Ojeda | Expr::Cast(ExprCast { attrs, .. }) 938808c999fSMiguel Ojeda | Expr::Closure(ExprClosure { attrs, .. }) 939808c999fSMiguel Ojeda | Expr::Const(ExprConst { attrs, .. }) 940808c999fSMiguel Ojeda | Expr::Continue(ExprContinue { attrs, .. }) 941808c999fSMiguel Ojeda | Expr::Field(ExprField { attrs, .. }) 942808c999fSMiguel Ojeda | Expr::ForLoop(ExprForLoop { attrs, .. }) 943808c999fSMiguel Ojeda | Expr::Group(ExprGroup { attrs, .. }) 944808c999fSMiguel Ojeda | Expr::If(ExprIf { attrs, .. }) 945808c999fSMiguel Ojeda | Expr::Index(ExprIndex { attrs, .. }) 946808c999fSMiguel Ojeda | Expr::Infer(ExprInfer { attrs, .. }) 947808c999fSMiguel Ojeda | Expr::Let(ExprLet { attrs, .. }) 948808c999fSMiguel Ojeda | Expr::Lit(ExprLit { attrs, .. }) 949808c999fSMiguel Ojeda | Expr::Loop(ExprLoop { attrs, .. }) 950808c999fSMiguel Ojeda | Expr::Macro(ExprMacro { attrs, .. }) 951808c999fSMiguel Ojeda | Expr::Match(ExprMatch { attrs, .. }) 952808c999fSMiguel Ojeda | Expr::MethodCall(ExprMethodCall { attrs, .. }) 953808c999fSMiguel Ojeda | Expr::Paren(ExprParen { attrs, .. }) 954808c999fSMiguel Ojeda | Expr::Path(ExprPath { attrs, .. }) 955808c999fSMiguel Ojeda | Expr::Range(ExprRange { attrs, .. }) 956808c999fSMiguel Ojeda | Expr::RawAddr(ExprRawAddr { attrs, .. }) 957808c999fSMiguel Ojeda | Expr::Reference(ExprReference { attrs, .. }) 958808c999fSMiguel Ojeda | Expr::Repeat(ExprRepeat { attrs, .. }) 959808c999fSMiguel Ojeda | Expr::Return(ExprReturn { attrs, .. }) 960808c999fSMiguel Ojeda | Expr::Struct(ExprStruct { attrs, .. }) 961808c999fSMiguel Ojeda | Expr::Try(ExprTry { attrs, .. }) 962808c999fSMiguel Ojeda | Expr::TryBlock(ExprTryBlock { attrs, .. }) 963808c999fSMiguel Ojeda | Expr::Tuple(ExprTuple { attrs, .. }) 964808c999fSMiguel Ojeda | Expr::Unary(ExprUnary { attrs, .. }) 965808c999fSMiguel Ojeda | Expr::Unsafe(ExprUnsafe { attrs, .. }) 966808c999fSMiguel Ojeda | Expr::While(ExprWhile { attrs, .. }) 967808c999fSMiguel Ojeda | Expr::Yield(ExprYield { attrs, .. }) => mem::replace(attrs, new), 968808c999fSMiguel Ojeda Expr::Verbatim(_) => Vec::new(), 969808c999fSMiguel Ojeda } 970808c999fSMiguel Ojeda } 971808c999fSMiguel Ojeda } 972808c999fSMiguel Ojeda 973808c999fSMiguel Ojeda ast_enum! { 974808c999fSMiguel Ojeda /// A struct or tuple struct field accessed in a struct literal or field 975808c999fSMiguel Ojeda /// expression. 976808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 977808c999fSMiguel Ojeda pub enum Member { 978808c999fSMiguel Ojeda /// A named field like `self.x`. 979808c999fSMiguel Ojeda Named(Ident), 980808c999fSMiguel Ojeda /// An unnamed field like `self.0`. 981808c999fSMiguel Ojeda Unnamed(Index), 982808c999fSMiguel Ojeda } 983808c999fSMiguel Ojeda } 984808c999fSMiguel Ojeda 985808c999fSMiguel Ojeda impl From<Ident> for Member { from(ident: Ident) -> Member986808c999fSMiguel Ojeda fn from(ident: Ident) -> Member { 987808c999fSMiguel Ojeda Member::Named(ident) 988808c999fSMiguel Ojeda } 989808c999fSMiguel Ojeda } 990808c999fSMiguel Ojeda 991808c999fSMiguel Ojeda impl From<Index> for Member { from(index: Index) -> Member992808c999fSMiguel Ojeda fn from(index: Index) -> Member { 993808c999fSMiguel Ojeda Member::Unnamed(index) 994808c999fSMiguel Ojeda } 995808c999fSMiguel Ojeda } 996808c999fSMiguel Ojeda 997808c999fSMiguel Ojeda impl From<usize> for Member { from(index: usize) -> Member998808c999fSMiguel Ojeda fn from(index: usize) -> Member { 999808c999fSMiguel Ojeda Member::Unnamed(Index::from(index)) 1000808c999fSMiguel Ojeda } 1001808c999fSMiguel Ojeda } 1002808c999fSMiguel Ojeda 1003808c999fSMiguel Ojeda impl Eq for Member {} 1004808c999fSMiguel Ojeda 1005808c999fSMiguel Ojeda impl PartialEq for Member { eq(&self, other: &Self) -> bool1006808c999fSMiguel Ojeda fn eq(&self, other: &Self) -> bool { 1007808c999fSMiguel Ojeda match (self, other) { 1008808c999fSMiguel Ojeda (Member::Named(this), Member::Named(other)) => this == other, 1009808c999fSMiguel Ojeda (Member::Unnamed(this), Member::Unnamed(other)) => this == other, 1010808c999fSMiguel Ojeda _ => false, 1011808c999fSMiguel Ojeda } 1012808c999fSMiguel Ojeda } 1013808c999fSMiguel Ojeda } 1014808c999fSMiguel Ojeda 1015808c999fSMiguel Ojeda impl Hash for Member { hash<H: Hasher>(&self, state: &mut H)1016808c999fSMiguel Ojeda fn hash<H: Hasher>(&self, state: &mut H) { 1017808c999fSMiguel Ojeda match self { 1018808c999fSMiguel Ojeda Member::Named(m) => m.hash(state), 1019808c999fSMiguel Ojeda Member::Unnamed(m) => m.hash(state), 1020808c999fSMiguel Ojeda } 1021808c999fSMiguel Ojeda } 1022808c999fSMiguel Ojeda } 1023808c999fSMiguel Ojeda 1024808c999fSMiguel Ojeda #[cfg(feature = "printing")] 1025808c999fSMiguel Ojeda impl IdentFragment for Member { fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result1026808c999fSMiguel Ojeda fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 1027808c999fSMiguel Ojeda match self { 1028808c999fSMiguel Ojeda Member::Named(m) => Display::fmt(m, formatter), 1029808c999fSMiguel Ojeda Member::Unnamed(m) => Display::fmt(&m.index, formatter), 1030808c999fSMiguel Ojeda } 1031808c999fSMiguel Ojeda } 1032808c999fSMiguel Ojeda span(&self) -> Option<Span>1033808c999fSMiguel Ojeda fn span(&self) -> Option<Span> { 1034808c999fSMiguel Ojeda match self { 1035808c999fSMiguel Ojeda Member::Named(m) => Some(m.span()), 1036808c999fSMiguel Ojeda Member::Unnamed(m) => Some(m.span), 1037808c999fSMiguel Ojeda } 1038808c999fSMiguel Ojeda } 1039808c999fSMiguel Ojeda } 1040808c999fSMiguel Ojeda 1041808c999fSMiguel Ojeda #[cfg(any(feature = "parsing", feature = "printing"))] 1042808c999fSMiguel Ojeda impl Member { is_named(&self) -> bool1043808c999fSMiguel Ojeda pub(crate) fn is_named(&self) -> bool { 1044808c999fSMiguel Ojeda match self { 1045808c999fSMiguel Ojeda Member::Named(_) => true, 1046808c999fSMiguel Ojeda Member::Unnamed(_) => false, 1047808c999fSMiguel Ojeda } 1048808c999fSMiguel Ojeda } 1049808c999fSMiguel Ojeda } 1050808c999fSMiguel Ojeda 1051808c999fSMiguel Ojeda ast_struct! { 1052808c999fSMiguel Ojeda /// The index of an unnamed tuple struct field. 1053808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 1054808c999fSMiguel Ojeda pub struct Index { 1055808c999fSMiguel Ojeda pub index: u32, 1056808c999fSMiguel Ojeda pub span: Span, 1057808c999fSMiguel Ojeda } 1058808c999fSMiguel Ojeda } 1059808c999fSMiguel Ojeda 1060808c999fSMiguel Ojeda impl From<usize> for Index { from(index: usize) -> Index1061808c999fSMiguel Ojeda fn from(index: usize) -> Index { 1062808c999fSMiguel Ojeda assert!(index < u32::MAX as usize); 1063808c999fSMiguel Ojeda Index { 1064808c999fSMiguel Ojeda index: index as u32, 1065808c999fSMiguel Ojeda span: Span::call_site(), 1066808c999fSMiguel Ojeda } 1067808c999fSMiguel Ojeda } 1068808c999fSMiguel Ojeda } 1069808c999fSMiguel Ojeda 1070808c999fSMiguel Ojeda impl Eq for Index {} 1071808c999fSMiguel Ojeda 1072808c999fSMiguel Ojeda impl PartialEq for Index { eq(&self, other: &Self) -> bool1073808c999fSMiguel Ojeda fn eq(&self, other: &Self) -> bool { 1074808c999fSMiguel Ojeda self.index == other.index 1075808c999fSMiguel Ojeda } 1076808c999fSMiguel Ojeda } 1077808c999fSMiguel Ojeda 1078808c999fSMiguel Ojeda impl Hash for Index { hash<H: Hasher>(&self, state: &mut H)1079808c999fSMiguel Ojeda fn hash<H: Hasher>(&self, state: &mut H) { 1080808c999fSMiguel Ojeda self.index.hash(state); 1081808c999fSMiguel Ojeda } 1082808c999fSMiguel Ojeda } 1083808c999fSMiguel Ojeda 1084808c999fSMiguel Ojeda #[cfg(feature = "printing")] 1085808c999fSMiguel Ojeda impl IdentFragment for Index { fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result1086808c999fSMiguel Ojeda fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 1087808c999fSMiguel Ojeda Display::fmt(&self.index, formatter) 1088808c999fSMiguel Ojeda } 1089808c999fSMiguel Ojeda span(&self) -> Option<Span>1090808c999fSMiguel Ojeda fn span(&self) -> Option<Span> { 1091808c999fSMiguel Ojeda Some(self.span) 1092808c999fSMiguel Ojeda } 1093808c999fSMiguel Ojeda } 1094808c999fSMiguel Ojeda 1095808c999fSMiguel Ojeda ast_struct! { 1096808c999fSMiguel Ojeda /// A field-value pair in a struct literal. 1097808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 1098808c999fSMiguel Ojeda pub struct FieldValue { 1099808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 1100808c999fSMiguel Ojeda pub member: Member, 1101808c999fSMiguel Ojeda 1102808c999fSMiguel Ojeda /// The colon in `Struct { x: x }`. If written in shorthand like 1103808c999fSMiguel Ojeda /// `Struct { x }`, there is no colon. 1104808c999fSMiguel Ojeda pub colon_token: Option<Token![:]>, 1105808c999fSMiguel Ojeda 1106808c999fSMiguel Ojeda pub expr: Expr, 1107808c999fSMiguel Ojeda } 1108808c999fSMiguel Ojeda } 1109808c999fSMiguel Ojeda 1110808c999fSMiguel Ojeda #[cfg(feature = "full")] 1111808c999fSMiguel Ojeda ast_struct! { 1112808c999fSMiguel Ojeda /// A lifetime labeling a `for`, `while`, or `loop`. 1113808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 1114808c999fSMiguel Ojeda pub struct Label { 1115808c999fSMiguel Ojeda pub name: Lifetime, 1116808c999fSMiguel Ojeda pub colon_token: Token![:], 1117808c999fSMiguel Ojeda } 1118808c999fSMiguel Ojeda } 1119808c999fSMiguel Ojeda 1120808c999fSMiguel Ojeda #[cfg(feature = "full")] 1121808c999fSMiguel Ojeda ast_struct! { 1122808c999fSMiguel Ojeda /// One arm of a `match` expression: `0..=10 => { return true; }`. 1123808c999fSMiguel Ojeda /// 1124808c999fSMiguel Ojeda /// As in: 1125808c999fSMiguel Ojeda /// 1126808c999fSMiguel Ojeda /// ``` 1127808c999fSMiguel Ojeda /// # fn f() -> bool { 1128808c999fSMiguel Ojeda /// # let n = 0; 1129808c999fSMiguel Ojeda /// match n { 1130808c999fSMiguel Ojeda /// 0..=10 => { 1131808c999fSMiguel Ojeda /// return true; 1132808c999fSMiguel Ojeda /// } 1133808c999fSMiguel Ojeda /// // ... 1134808c999fSMiguel Ojeda /// # _ => {} 1135808c999fSMiguel Ojeda /// } 1136808c999fSMiguel Ojeda /// # false 1137808c999fSMiguel Ojeda /// # } 1138808c999fSMiguel Ojeda /// ``` 1139808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 1140808c999fSMiguel Ojeda pub struct Arm { 1141808c999fSMiguel Ojeda pub attrs: Vec<Attribute>, 1142808c999fSMiguel Ojeda pub pat: Pat, 1143808c999fSMiguel Ojeda pub guard: Option<(Token![if], Box<Expr>)>, 1144808c999fSMiguel Ojeda pub fat_arrow_token: Token![=>], 1145808c999fSMiguel Ojeda pub body: Box<Expr>, 1146808c999fSMiguel Ojeda pub comma: Option<Token![,]>, 1147808c999fSMiguel Ojeda } 1148808c999fSMiguel Ojeda } 1149808c999fSMiguel Ojeda 1150808c999fSMiguel Ojeda #[cfg(feature = "full")] 1151808c999fSMiguel Ojeda ast_enum! { 1152808c999fSMiguel Ojeda /// Limit types of a range, inclusive or exclusive. 1153808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 1154808c999fSMiguel Ojeda pub enum RangeLimits { 1155808c999fSMiguel Ojeda /// Inclusive at the beginning, exclusive at the end. 1156808c999fSMiguel Ojeda HalfOpen(Token![..]), 1157808c999fSMiguel Ojeda /// Inclusive at the beginning and end. 1158808c999fSMiguel Ojeda Closed(Token![..=]), 1159808c999fSMiguel Ojeda } 1160808c999fSMiguel Ojeda } 1161808c999fSMiguel Ojeda 1162808c999fSMiguel Ojeda #[cfg(feature = "full")] 1163808c999fSMiguel Ojeda ast_enum! { 1164808c999fSMiguel Ojeda /// Mutability of a raw pointer (`*const T`, `*mut T`), in which non-mutable 1165808c999fSMiguel Ojeda /// isn't the implicit default. 1166808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "full")))] 1167808c999fSMiguel Ojeda pub enum PointerMutability { 1168808c999fSMiguel Ojeda Const(Token![const]), 1169808c999fSMiguel Ojeda Mut(Token![mut]), 1170808c999fSMiguel Ojeda } 1171808c999fSMiguel Ojeda } 1172808c999fSMiguel Ojeda 1173808c999fSMiguel Ojeda #[cfg(feature = "parsing")] 1174808c999fSMiguel Ojeda pub(crate) mod parsing { 1175808c999fSMiguel Ojeda #[cfg(feature = "full")] 1176808c999fSMiguel Ojeda use crate::attr; 1177808c999fSMiguel Ojeda use crate::attr::Attribute; 1178808c999fSMiguel Ojeda #[cfg(feature = "full")] 1179808c999fSMiguel Ojeda use crate::classify; 1180808c999fSMiguel Ojeda use crate::error::{Error, Result}; 1181808c999fSMiguel Ojeda #[cfg(feature = "full")] 1182808c999fSMiguel Ojeda use crate::expr::{ 1183808c999fSMiguel Ojeda Arm, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure, 1184808c999fSMiguel Ojeda ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch, 1185808c999fSMiguel Ojeda ExprRange, ExprRawAddr, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprUnsafe, 1186808c999fSMiguel Ojeda ExprWhile, ExprYield, Label, PointerMutability, RangeLimits, 1187808c999fSMiguel Ojeda }; 1188808c999fSMiguel Ojeda use crate::expr::{ 1189808c999fSMiguel Ojeda Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprGroup, ExprIndex, ExprLit, ExprMacro, 1190808c999fSMiguel Ojeda ExprMethodCall, ExprParen, ExprPath, ExprReference, ExprStruct, ExprTuple, ExprUnary, 1191808c999fSMiguel Ojeda FieldValue, Index, Member, 1192808c999fSMiguel Ojeda }; 1193808c999fSMiguel Ojeda #[cfg(feature = "full")] 1194808c999fSMiguel Ojeda use crate::generics::{self, BoundLifetimes}; 1195808c999fSMiguel Ojeda use crate::ident::Ident; 1196808c999fSMiguel Ojeda #[cfg(feature = "full")] 1197808c999fSMiguel Ojeda use crate::lifetime::Lifetime; 1198808c999fSMiguel Ojeda use crate::lit::{Lit, LitFloat, LitInt}; 1199808c999fSMiguel Ojeda use crate::mac::{self, Macro}; 1200808c999fSMiguel Ojeda use crate::op::BinOp; 1201808c999fSMiguel Ojeda use crate::parse::discouraged::Speculative as _; 1202808c999fSMiguel Ojeda #[cfg(feature = "full")] 1203808c999fSMiguel Ojeda use crate::parse::ParseBuffer; 1204808c999fSMiguel Ojeda use crate::parse::{Parse, ParseStream}; 1205808c999fSMiguel Ojeda #[cfg(feature = "full")] 1206808c999fSMiguel Ojeda use crate::pat::{Pat, PatType}; 1207808c999fSMiguel Ojeda use crate::path::{self, AngleBracketedGenericArguments, Path, QSelf}; 1208808c999fSMiguel Ojeda use crate::precedence::Precedence; 1209808c999fSMiguel Ojeda use crate::punctuated::Punctuated; 1210808c999fSMiguel Ojeda #[cfg(feature = "full")] 1211808c999fSMiguel Ojeda use crate::stmt::Block; 1212808c999fSMiguel Ojeda use crate::token; 1213808c999fSMiguel Ojeda use crate::ty; 1214808c999fSMiguel Ojeda #[cfg(feature = "full")] 1215808c999fSMiguel Ojeda use crate::ty::{ReturnType, Type}; 1216808c999fSMiguel Ojeda use crate::verbatim; 1217808c999fSMiguel Ojeda #[cfg(feature = "full")] 1218808c999fSMiguel Ojeda use proc_macro2::{Span, TokenStream}; 1219808c999fSMiguel Ojeda use std::mem; 1220808c999fSMiguel Ojeda 1221808c999fSMiguel Ojeda // When we're parsing expressions which occur before blocks, like in an if 1222808c999fSMiguel Ojeda // statement's condition, we cannot parse a struct literal. 1223808c999fSMiguel Ojeda // 1224808c999fSMiguel Ojeda // Struct literals are ambiguous in certain positions 1225808c999fSMiguel Ojeda // https://github.com/rust-lang/rfcs/pull/92 1226808c999fSMiguel Ojeda #[cfg(feature = "full")] 1227808c999fSMiguel Ojeda pub(super) struct AllowStruct(pub bool); 1228808c999fSMiguel Ojeda 1229808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 1230808c999fSMiguel Ojeda impl Parse for Expr { parse(input: ParseStream) -> Result<Self>1231808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 1232808c999fSMiguel Ojeda ambiguous_expr( 1233808c999fSMiguel Ojeda input, 1234808c999fSMiguel Ojeda #[cfg(feature = "full")] 1235808c999fSMiguel Ojeda AllowStruct(true), 1236808c999fSMiguel Ojeda ) 1237808c999fSMiguel Ojeda } 1238808c999fSMiguel Ojeda } 1239808c999fSMiguel Ojeda 1240808c999fSMiguel Ojeda #[cfg(feature = "full")] parse_with_earlier_boundary_rule(input: ParseStream) -> Result<Expr>1241808c999fSMiguel Ojeda pub(super) fn parse_with_earlier_boundary_rule(input: ParseStream) -> Result<Expr> { 1242808c999fSMiguel Ojeda let mut attrs = input.call(expr_attrs)?; 1243808c999fSMiguel Ojeda let mut expr = if input.peek(token::Group) { 1244808c999fSMiguel Ojeda let allow_struct = AllowStruct(true); 1245808c999fSMiguel Ojeda let atom = expr_group(input, allow_struct)?; 1246808c999fSMiguel Ojeda if continue_parsing_early(&atom) { 1247808c999fSMiguel Ojeda trailer_helper(input, atom)? 1248808c999fSMiguel Ojeda } else { 1249808c999fSMiguel Ojeda atom 1250808c999fSMiguel Ojeda } 1251808c999fSMiguel Ojeda } else if input.peek(Token![if]) { 1252808c999fSMiguel Ojeda Expr::If(input.parse()?) 1253808c999fSMiguel Ojeda } else if input.peek(Token![while]) { 1254808c999fSMiguel Ojeda Expr::While(input.parse()?) 1255808c999fSMiguel Ojeda } else if input.peek(Token![for]) 1256808c999fSMiguel Ojeda && !generics::parsing::choose_generics_over_qpath_after_keyword(input) 1257808c999fSMiguel Ojeda { 1258808c999fSMiguel Ojeda Expr::ForLoop(input.parse()?) 1259808c999fSMiguel Ojeda } else if input.peek(Token![loop]) { 1260808c999fSMiguel Ojeda Expr::Loop(input.parse()?) 1261808c999fSMiguel Ojeda } else if input.peek(Token![match]) { 1262808c999fSMiguel Ojeda Expr::Match(input.parse()?) 1263808c999fSMiguel Ojeda } else if input.peek(Token![try]) && input.peek2(token::Brace) { 1264808c999fSMiguel Ojeda Expr::TryBlock(input.parse()?) 1265808c999fSMiguel Ojeda } else if input.peek(Token![unsafe]) { 1266808c999fSMiguel Ojeda Expr::Unsafe(input.parse()?) 1267808c999fSMiguel Ojeda } else if input.peek(Token![const]) && input.peek2(token::Brace) { 1268808c999fSMiguel Ojeda Expr::Const(input.parse()?) 1269808c999fSMiguel Ojeda } else if input.peek(token::Brace) { 1270808c999fSMiguel Ojeda Expr::Block(input.parse()?) 1271808c999fSMiguel Ojeda } else if input.peek(Lifetime) { 1272808c999fSMiguel Ojeda atom_labeled(input)? 1273808c999fSMiguel Ojeda } else { 1274808c999fSMiguel Ojeda let allow_struct = AllowStruct(true); 1275808c999fSMiguel Ojeda unary_expr(input, allow_struct)? 1276808c999fSMiguel Ojeda }; 1277808c999fSMiguel Ojeda 1278808c999fSMiguel Ojeda if continue_parsing_early(&expr) { 1279808c999fSMiguel Ojeda attrs.extend(expr.replace_attrs(Vec::new())); 1280808c999fSMiguel Ojeda expr.replace_attrs(attrs); 1281808c999fSMiguel Ojeda 1282808c999fSMiguel Ojeda let allow_struct = AllowStruct(true); 1283808c999fSMiguel Ojeda return parse_expr(input, expr, allow_struct, Precedence::MIN); 1284808c999fSMiguel Ojeda } 1285808c999fSMiguel Ojeda 1286808c999fSMiguel Ojeda if input.peek(Token![.]) && !input.peek(Token![..]) || input.peek(Token![?]) { 1287808c999fSMiguel Ojeda expr = trailer_helper(input, expr)?; 1288808c999fSMiguel Ojeda 1289808c999fSMiguel Ojeda attrs.extend(expr.replace_attrs(Vec::new())); 1290808c999fSMiguel Ojeda expr.replace_attrs(attrs); 1291808c999fSMiguel Ojeda 1292808c999fSMiguel Ojeda let allow_struct = AllowStruct(true); 1293808c999fSMiguel Ojeda return parse_expr(input, expr, allow_struct, Precedence::MIN); 1294808c999fSMiguel Ojeda } 1295808c999fSMiguel Ojeda 1296808c999fSMiguel Ojeda attrs.extend(expr.replace_attrs(Vec::new())); 1297808c999fSMiguel Ojeda expr.replace_attrs(attrs); 1298808c999fSMiguel Ojeda Ok(expr) 1299808c999fSMiguel Ojeda } 1300808c999fSMiguel Ojeda 1301808c999fSMiguel Ojeda #[cfg(feature = "full")] 1302808c999fSMiguel Ojeda impl Copy for AllowStruct {} 1303808c999fSMiguel Ojeda 1304808c999fSMiguel Ojeda #[cfg(feature = "full")] 1305808c999fSMiguel Ojeda impl Clone for AllowStruct { clone(&self) -> Self1306808c999fSMiguel Ojeda fn clone(&self) -> Self { 1307808c999fSMiguel Ojeda *self 1308808c999fSMiguel Ojeda } 1309808c999fSMiguel Ojeda } 1310808c999fSMiguel Ojeda 1311808c999fSMiguel Ojeda #[cfg(feature = "full")] parse_expr( input: ParseStream, mut lhs: Expr, allow_struct: AllowStruct, base: Precedence, ) -> Result<Expr>1312808c999fSMiguel Ojeda fn parse_expr( 1313808c999fSMiguel Ojeda input: ParseStream, 1314808c999fSMiguel Ojeda mut lhs: Expr, 1315808c999fSMiguel Ojeda allow_struct: AllowStruct, 1316808c999fSMiguel Ojeda base: Precedence, 1317808c999fSMiguel Ojeda ) -> Result<Expr> { 1318808c999fSMiguel Ojeda loop { 1319808c999fSMiguel Ojeda let ahead = input.fork(); 1320808c999fSMiguel Ojeda if let Expr::Range(_) = lhs { 1321808c999fSMiguel Ojeda // A range cannot be the left-hand side of another binary operator. 1322808c999fSMiguel Ojeda break; 1323808c999fSMiguel Ojeda } else if let Ok(op) = ahead.parse::<BinOp>() { 1324808c999fSMiguel Ojeda let precedence = Precedence::of_binop(&op); 1325808c999fSMiguel Ojeda if precedence < base { 1326808c999fSMiguel Ojeda break; 1327808c999fSMiguel Ojeda } 1328808c999fSMiguel Ojeda if precedence == Precedence::Assign { 1329808c999fSMiguel Ojeda if let Expr::Range(_) = lhs { 1330808c999fSMiguel Ojeda break; 1331808c999fSMiguel Ojeda } 1332808c999fSMiguel Ojeda } 1333808c999fSMiguel Ojeda if precedence == Precedence::Compare { 1334808c999fSMiguel Ojeda if let Expr::Binary(lhs) = &lhs { 1335808c999fSMiguel Ojeda if Precedence::of_binop(&lhs.op) == Precedence::Compare { 1336808c999fSMiguel Ojeda return Err(input.error("comparison operators cannot be chained")); 1337808c999fSMiguel Ojeda } 1338808c999fSMiguel Ojeda } 1339808c999fSMiguel Ojeda } 1340808c999fSMiguel Ojeda input.advance_to(&ahead); 1341808c999fSMiguel Ojeda let right = parse_binop_rhs(input, allow_struct, precedence)?; 1342808c999fSMiguel Ojeda lhs = Expr::Binary(ExprBinary { 1343808c999fSMiguel Ojeda attrs: Vec::new(), 1344808c999fSMiguel Ojeda left: Box::new(lhs), 1345808c999fSMiguel Ojeda op, 1346808c999fSMiguel Ojeda right, 1347808c999fSMiguel Ojeda }); 1348808c999fSMiguel Ojeda } else if Precedence::Assign >= base 1349808c999fSMiguel Ojeda && input.peek(Token![=]) 1350808c999fSMiguel Ojeda && !input.peek(Token![=>]) 1351808c999fSMiguel Ojeda && match lhs { 1352808c999fSMiguel Ojeda Expr::Range(_) => false, 1353808c999fSMiguel Ojeda _ => true, 1354808c999fSMiguel Ojeda } 1355808c999fSMiguel Ojeda { 1356808c999fSMiguel Ojeda let eq_token: Token![=] = input.parse()?; 1357808c999fSMiguel Ojeda let right = parse_binop_rhs(input, allow_struct, Precedence::Assign)?; 1358808c999fSMiguel Ojeda lhs = Expr::Assign(ExprAssign { 1359808c999fSMiguel Ojeda attrs: Vec::new(), 1360808c999fSMiguel Ojeda left: Box::new(lhs), 1361808c999fSMiguel Ojeda eq_token, 1362808c999fSMiguel Ojeda right, 1363808c999fSMiguel Ojeda }); 1364808c999fSMiguel Ojeda } else if Precedence::Range >= base && input.peek(Token![..]) { 1365808c999fSMiguel Ojeda let limits: RangeLimits = input.parse()?; 1366808c999fSMiguel Ojeda let end = parse_range_end(input, &limits, allow_struct)?; 1367808c999fSMiguel Ojeda lhs = Expr::Range(ExprRange { 1368808c999fSMiguel Ojeda attrs: Vec::new(), 1369808c999fSMiguel Ojeda start: Some(Box::new(lhs)), 1370808c999fSMiguel Ojeda limits, 1371808c999fSMiguel Ojeda end, 1372808c999fSMiguel Ojeda }); 1373808c999fSMiguel Ojeda } else if Precedence::Cast >= base && input.peek(Token![as]) { 1374808c999fSMiguel Ojeda let as_token: Token![as] = input.parse()?; 1375808c999fSMiguel Ojeda let allow_plus = false; 1376808c999fSMiguel Ojeda let allow_group_generic = false; 1377808c999fSMiguel Ojeda let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?; 1378808c999fSMiguel Ojeda check_cast(input)?; 1379808c999fSMiguel Ojeda lhs = Expr::Cast(ExprCast { 1380808c999fSMiguel Ojeda attrs: Vec::new(), 1381808c999fSMiguel Ojeda expr: Box::new(lhs), 1382808c999fSMiguel Ojeda as_token, 1383808c999fSMiguel Ojeda ty: Box::new(ty), 1384808c999fSMiguel Ojeda }); 1385808c999fSMiguel Ojeda } else { 1386808c999fSMiguel Ojeda break; 1387808c999fSMiguel Ojeda } 1388808c999fSMiguel Ojeda } 1389808c999fSMiguel Ojeda Ok(lhs) 1390808c999fSMiguel Ojeda } 1391808c999fSMiguel Ojeda 1392808c999fSMiguel Ojeda #[cfg(not(feature = "full"))] parse_expr(input: ParseStream, mut lhs: Expr, base: Precedence) -> Result<Expr>1393808c999fSMiguel Ojeda fn parse_expr(input: ParseStream, mut lhs: Expr, base: Precedence) -> Result<Expr> { 1394808c999fSMiguel Ojeda loop { 1395808c999fSMiguel Ojeda let ahead = input.fork(); 1396808c999fSMiguel Ojeda if let Ok(op) = ahead.parse::<BinOp>() { 1397808c999fSMiguel Ojeda let precedence = Precedence::of_binop(&op); 1398808c999fSMiguel Ojeda if precedence < base { 1399808c999fSMiguel Ojeda break; 1400808c999fSMiguel Ojeda } 1401808c999fSMiguel Ojeda if precedence == Precedence::Compare { 1402808c999fSMiguel Ojeda if let Expr::Binary(lhs) = &lhs { 1403808c999fSMiguel Ojeda if Precedence::of_binop(&lhs.op) == Precedence::Compare { 1404808c999fSMiguel Ojeda return Err(input.error("comparison operators cannot be chained")); 1405808c999fSMiguel Ojeda } 1406808c999fSMiguel Ojeda } 1407808c999fSMiguel Ojeda } 1408808c999fSMiguel Ojeda input.advance_to(&ahead); 1409808c999fSMiguel Ojeda let right = parse_binop_rhs(input, precedence)?; 1410808c999fSMiguel Ojeda lhs = Expr::Binary(ExprBinary { 1411808c999fSMiguel Ojeda attrs: Vec::new(), 1412808c999fSMiguel Ojeda left: Box::new(lhs), 1413808c999fSMiguel Ojeda op, 1414808c999fSMiguel Ojeda right, 1415808c999fSMiguel Ojeda }); 1416808c999fSMiguel Ojeda } else if Precedence::Cast >= base && input.peek(Token![as]) { 1417808c999fSMiguel Ojeda let as_token: Token![as] = input.parse()?; 1418808c999fSMiguel Ojeda let allow_plus = false; 1419808c999fSMiguel Ojeda let allow_group_generic = false; 1420808c999fSMiguel Ojeda let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?; 1421808c999fSMiguel Ojeda check_cast(input)?; 1422808c999fSMiguel Ojeda lhs = Expr::Cast(ExprCast { 1423808c999fSMiguel Ojeda attrs: Vec::new(), 1424808c999fSMiguel Ojeda expr: Box::new(lhs), 1425808c999fSMiguel Ojeda as_token, 1426808c999fSMiguel Ojeda ty: Box::new(ty), 1427808c999fSMiguel Ojeda }); 1428808c999fSMiguel Ojeda } else { 1429808c999fSMiguel Ojeda break; 1430808c999fSMiguel Ojeda } 1431808c999fSMiguel Ojeda } 1432808c999fSMiguel Ojeda Ok(lhs) 1433808c999fSMiguel Ojeda } 1434808c999fSMiguel Ojeda parse_binop_rhs( input: ParseStream, #[cfg(feature = "full")] allow_struct: AllowStruct, precedence: Precedence, ) -> Result<Box<Expr>>1435808c999fSMiguel Ojeda fn parse_binop_rhs( 1436808c999fSMiguel Ojeda input: ParseStream, 1437808c999fSMiguel Ojeda #[cfg(feature = "full")] allow_struct: AllowStruct, 1438808c999fSMiguel Ojeda precedence: Precedence, 1439808c999fSMiguel Ojeda ) -> Result<Box<Expr>> { 1440808c999fSMiguel Ojeda let mut rhs = unary_expr( 1441808c999fSMiguel Ojeda input, 1442808c999fSMiguel Ojeda #[cfg(feature = "full")] 1443808c999fSMiguel Ojeda allow_struct, 1444808c999fSMiguel Ojeda )?; 1445808c999fSMiguel Ojeda loop { 1446808c999fSMiguel Ojeda let next = peek_precedence(input); 1447808c999fSMiguel Ojeda if next > precedence || next == precedence && precedence == Precedence::Assign { 1448808c999fSMiguel Ojeda let cursor = input.cursor(); 1449808c999fSMiguel Ojeda rhs = parse_expr( 1450808c999fSMiguel Ojeda input, 1451808c999fSMiguel Ojeda rhs, 1452808c999fSMiguel Ojeda #[cfg(feature = "full")] 1453808c999fSMiguel Ojeda allow_struct, 1454808c999fSMiguel Ojeda next, 1455808c999fSMiguel Ojeda )?; 1456808c999fSMiguel Ojeda if cursor == input.cursor() { 1457808c999fSMiguel Ojeda // Bespoke grammar restrictions separate from precedence can 1458808c999fSMiguel Ojeda // cause parsing to not advance, such as `..a` being 1459808c999fSMiguel Ojeda // disallowed in the left-hand side of binary operators, 1460808c999fSMiguel Ojeda // even ones that have lower precedence than `..`. 1461808c999fSMiguel Ojeda break; 1462808c999fSMiguel Ojeda } 1463808c999fSMiguel Ojeda } else { 1464808c999fSMiguel Ojeda break; 1465808c999fSMiguel Ojeda } 1466808c999fSMiguel Ojeda } 1467808c999fSMiguel Ojeda Ok(Box::new(rhs)) 1468808c999fSMiguel Ojeda } 1469808c999fSMiguel Ojeda peek_precedence(input: ParseStream) -> Precedence1470808c999fSMiguel Ojeda fn peek_precedence(input: ParseStream) -> Precedence { 1471808c999fSMiguel Ojeda if let Ok(op) = input.fork().parse() { 1472808c999fSMiguel Ojeda Precedence::of_binop(&op) 1473808c999fSMiguel Ojeda } else if input.peek(Token![=]) && !input.peek(Token![=>]) { 1474808c999fSMiguel Ojeda Precedence::Assign 1475808c999fSMiguel Ojeda } else if input.peek(Token![..]) { 1476808c999fSMiguel Ojeda Precedence::Range 1477808c999fSMiguel Ojeda } else if input.peek(Token![as]) { 1478808c999fSMiguel Ojeda Precedence::Cast 1479808c999fSMiguel Ojeda } else { 1480808c999fSMiguel Ojeda Precedence::MIN 1481808c999fSMiguel Ojeda } 1482808c999fSMiguel Ojeda } 1483808c999fSMiguel Ojeda 1484808c999fSMiguel Ojeda // Parse an arbitrary expression. ambiguous_expr( input: ParseStream, #[cfg(feature = "full")] allow_struct: AllowStruct, ) -> Result<Expr>1485808c999fSMiguel Ojeda pub(super) fn ambiguous_expr( 1486808c999fSMiguel Ojeda input: ParseStream, 1487808c999fSMiguel Ojeda #[cfg(feature = "full")] allow_struct: AllowStruct, 1488808c999fSMiguel Ojeda ) -> Result<Expr> { 1489808c999fSMiguel Ojeda let lhs = unary_expr( 1490808c999fSMiguel Ojeda input, 1491808c999fSMiguel Ojeda #[cfg(feature = "full")] 1492808c999fSMiguel Ojeda allow_struct, 1493808c999fSMiguel Ojeda )?; 1494808c999fSMiguel Ojeda parse_expr( 1495808c999fSMiguel Ojeda input, 1496808c999fSMiguel Ojeda lhs, 1497808c999fSMiguel Ojeda #[cfg(feature = "full")] 1498808c999fSMiguel Ojeda allow_struct, 1499808c999fSMiguel Ojeda Precedence::MIN, 1500808c999fSMiguel Ojeda ) 1501808c999fSMiguel Ojeda } 1502808c999fSMiguel Ojeda 1503808c999fSMiguel Ojeda #[cfg(feature = "full")] expr_attrs(input: ParseStream) -> Result<Vec<Attribute>>1504808c999fSMiguel Ojeda fn expr_attrs(input: ParseStream) -> Result<Vec<Attribute>> { 1505808c999fSMiguel Ojeda let mut attrs = Vec::new(); 1506808c999fSMiguel Ojeda while !input.peek(token::Group) && input.peek(Token![#]) { 1507808c999fSMiguel Ojeda attrs.push(input.call(attr::parsing::single_parse_outer)?); 1508808c999fSMiguel Ojeda } 1509808c999fSMiguel Ojeda Ok(attrs) 1510808c999fSMiguel Ojeda } 1511808c999fSMiguel Ojeda 1512808c999fSMiguel Ojeda // <UnOp> <trailer> 1513808c999fSMiguel Ojeda // & <trailer> 1514808c999fSMiguel Ojeda // &mut <trailer> 1515808c999fSMiguel Ojeda // box <trailer> 1516808c999fSMiguel Ojeda #[cfg(feature = "full")] unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1517808c999fSMiguel Ojeda fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> { 1518808c999fSMiguel Ojeda let begin = input.fork(); 1519808c999fSMiguel Ojeda let attrs = input.call(expr_attrs)?; 1520808c999fSMiguel Ojeda if input.peek(token::Group) { 1521808c999fSMiguel Ojeda return trailer_expr(begin, attrs, input, allow_struct); 1522808c999fSMiguel Ojeda } 1523808c999fSMiguel Ojeda 1524808c999fSMiguel Ojeda if input.peek(Token![&]) { 1525808c999fSMiguel Ojeda let and_token: Token![&] = input.parse()?; 1526808c999fSMiguel Ojeda let raw: Option<Token![raw]> = if input.peek(Token![raw]) 1527808c999fSMiguel Ojeda && (input.peek2(Token![mut]) || input.peek2(Token![const])) 1528808c999fSMiguel Ojeda { 1529808c999fSMiguel Ojeda Some(input.parse()?) 1530808c999fSMiguel Ojeda } else { 1531808c999fSMiguel Ojeda None 1532808c999fSMiguel Ojeda }; 1533808c999fSMiguel Ojeda let mutability: Option<Token![mut]> = input.parse()?; 1534808c999fSMiguel Ojeda let const_token: Option<Token![const]> = if raw.is_some() && mutability.is_none() { 1535808c999fSMiguel Ojeda Some(input.parse()?) 1536808c999fSMiguel Ojeda } else { 1537808c999fSMiguel Ojeda None 1538808c999fSMiguel Ojeda }; 1539808c999fSMiguel Ojeda let expr = Box::new(unary_expr(input, allow_struct)?); 1540808c999fSMiguel Ojeda if let Some(raw) = raw { 1541808c999fSMiguel Ojeda Ok(Expr::RawAddr(ExprRawAddr { 1542808c999fSMiguel Ojeda attrs, 1543808c999fSMiguel Ojeda and_token, 1544808c999fSMiguel Ojeda raw, 1545808c999fSMiguel Ojeda mutability: match mutability { 1546808c999fSMiguel Ojeda Some(mut_token) => PointerMutability::Mut(mut_token), 1547808c999fSMiguel Ojeda None => PointerMutability::Const(const_token.unwrap()), 1548808c999fSMiguel Ojeda }, 1549808c999fSMiguel Ojeda expr, 1550808c999fSMiguel Ojeda })) 1551808c999fSMiguel Ojeda } else { 1552808c999fSMiguel Ojeda Ok(Expr::Reference(ExprReference { 1553808c999fSMiguel Ojeda attrs, 1554808c999fSMiguel Ojeda and_token, 1555808c999fSMiguel Ojeda mutability, 1556808c999fSMiguel Ojeda expr, 1557808c999fSMiguel Ojeda })) 1558808c999fSMiguel Ojeda } 1559808c999fSMiguel Ojeda } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) { 1560808c999fSMiguel Ojeda expr_unary(input, attrs, allow_struct).map(Expr::Unary) 1561808c999fSMiguel Ojeda } else { 1562808c999fSMiguel Ojeda trailer_expr(begin, attrs, input, allow_struct) 1563808c999fSMiguel Ojeda } 1564808c999fSMiguel Ojeda } 1565808c999fSMiguel Ojeda 1566808c999fSMiguel Ojeda #[cfg(not(feature = "full"))] unary_expr(input: ParseStream) -> Result<Expr>1567808c999fSMiguel Ojeda fn unary_expr(input: ParseStream) -> Result<Expr> { 1568808c999fSMiguel Ojeda if input.peek(Token![&]) { 1569808c999fSMiguel Ojeda Ok(Expr::Reference(ExprReference { 1570808c999fSMiguel Ojeda attrs: Vec::new(), 1571808c999fSMiguel Ojeda and_token: input.parse()?, 1572808c999fSMiguel Ojeda mutability: input.parse()?, 1573808c999fSMiguel Ojeda expr: Box::new(unary_expr(input)?), 1574808c999fSMiguel Ojeda })) 1575808c999fSMiguel Ojeda } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) { 1576808c999fSMiguel Ojeda Ok(Expr::Unary(ExprUnary { 1577808c999fSMiguel Ojeda attrs: Vec::new(), 1578808c999fSMiguel Ojeda op: input.parse()?, 1579808c999fSMiguel Ojeda expr: Box::new(unary_expr(input)?), 1580808c999fSMiguel Ojeda })) 1581808c999fSMiguel Ojeda } else { 1582808c999fSMiguel Ojeda trailer_expr(input) 1583808c999fSMiguel Ojeda } 1584808c999fSMiguel Ojeda } 1585808c999fSMiguel Ojeda 1586808c999fSMiguel Ojeda // <atom> (..<args>) ... 1587808c999fSMiguel Ojeda // <atom> . <ident> (..<args>) ... 1588808c999fSMiguel Ojeda // <atom> . <ident> ... 1589808c999fSMiguel Ojeda // <atom> . <lit> ... 1590808c999fSMiguel Ojeda // <atom> [ <expr> ] ... 1591808c999fSMiguel Ojeda // <atom> ? ... 1592808c999fSMiguel Ojeda #[cfg(feature = "full")] trailer_expr( begin: ParseBuffer, mut attrs: Vec<Attribute>, input: ParseStream, allow_struct: AllowStruct, ) -> Result<Expr>1593808c999fSMiguel Ojeda fn trailer_expr( 1594808c999fSMiguel Ojeda begin: ParseBuffer, 1595808c999fSMiguel Ojeda mut attrs: Vec<Attribute>, 1596808c999fSMiguel Ojeda input: ParseStream, 1597808c999fSMiguel Ojeda allow_struct: AllowStruct, 1598808c999fSMiguel Ojeda ) -> Result<Expr> { 1599808c999fSMiguel Ojeda let atom = atom_expr(input, allow_struct)?; 1600808c999fSMiguel Ojeda let mut e = trailer_helper(input, atom)?; 1601808c999fSMiguel Ojeda 1602808c999fSMiguel Ojeda if let Expr::Verbatim(tokens) = &mut e { 1603808c999fSMiguel Ojeda *tokens = verbatim::between(&begin, input); 1604808c999fSMiguel Ojeda } else if !attrs.is_empty() { 1605808c999fSMiguel Ojeda if let Expr::Range(range) = e { 1606808c999fSMiguel Ojeda let spans: &[Span] = match &range.limits { 1607808c999fSMiguel Ojeda RangeLimits::HalfOpen(limits) => &limits.spans, 1608808c999fSMiguel Ojeda RangeLimits::Closed(limits) => &limits.spans, 1609808c999fSMiguel Ojeda }; 1610808c999fSMiguel Ojeda return Err(crate::error::new2( 1611808c999fSMiguel Ojeda spans[0], 1612808c999fSMiguel Ojeda *spans.last().unwrap(), 1613808c999fSMiguel Ojeda "attributes are not allowed on range expressions starting with `..`", 1614808c999fSMiguel Ojeda )); 1615808c999fSMiguel Ojeda } 1616808c999fSMiguel Ojeda let inner_attrs = e.replace_attrs(Vec::new()); 1617808c999fSMiguel Ojeda attrs.extend(inner_attrs); 1618808c999fSMiguel Ojeda e.replace_attrs(attrs); 1619808c999fSMiguel Ojeda } 1620808c999fSMiguel Ojeda 1621808c999fSMiguel Ojeda Ok(e) 1622808c999fSMiguel Ojeda } 1623808c999fSMiguel Ojeda 1624808c999fSMiguel Ojeda #[cfg(feature = "full")] trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr>1625808c999fSMiguel Ojeda fn trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr> { 1626808c999fSMiguel Ojeda loop { 1627808c999fSMiguel Ojeda if input.peek(token::Paren) { 1628808c999fSMiguel Ojeda let content; 1629808c999fSMiguel Ojeda e = Expr::Call(ExprCall { 1630808c999fSMiguel Ojeda attrs: Vec::new(), 1631808c999fSMiguel Ojeda func: Box::new(e), 1632808c999fSMiguel Ojeda paren_token: parenthesized!(content in input), 1633808c999fSMiguel Ojeda args: content.parse_terminated(Expr::parse, Token![,])?, 1634808c999fSMiguel Ojeda }); 1635808c999fSMiguel Ojeda } else if input.peek(Token![.]) 1636808c999fSMiguel Ojeda && !input.peek(Token![..]) 1637808c999fSMiguel Ojeda && match e { 1638808c999fSMiguel Ojeda Expr::Range(_) => false, 1639808c999fSMiguel Ojeda _ => true, 1640808c999fSMiguel Ojeda } 1641808c999fSMiguel Ojeda { 1642808c999fSMiguel Ojeda let mut dot_token: Token![.] = input.parse()?; 1643808c999fSMiguel Ojeda 1644808c999fSMiguel Ojeda let float_token: Option<LitFloat> = input.parse()?; 1645808c999fSMiguel Ojeda if let Some(float_token) = float_token { 1646808c999fSMiguel Ojeda if multi_index(&mut e, &mut dot_token, float_token)? { 1647808c999fSMiguel Ojeda continue; 1648808c999fSMiguel Ojeda } 1649808c999fSMiguel Ojeda } 1650808c999fSMiguel Ojeda 1651808c999fSMiguel Ojeda let await_token: Option<Token![await]> = input.parse()?; 1652808c999fSMiguel Ojeda if let Some(await_token) = await_token { 1653808c999fSMiguel Ojeda e = Expr::Await(ExprAwait { 1654808c999fSMiguel Ojeda attrs: Vec::new(), 1655808c999fSMiguel Ojeda base: Box::new(e), 1656808c999fSMiguel Ojeda dot_token, 1657808c999fSMiguel Ojeda await_token, 1658808c999fSMiguel Ojeda }); 1659808c999fSMiguel Ojeda continue; 1660808c999fSMiguel Ojeda } 1661808c999fSMiguel Ojeda 1662808c999fSMiguel Ojeda let member: Member = input.parse()?; 1663808c999fSMiguel Ojeda let turbofish = if member.is_named() && input.peek(Token![::]) { 1664808c999fSMiguel Ojeda Some(AngleBracketedGenericArguments::parse_turbofish(input)?) 1665808c999fSMiguel Ojeda } else { 1666808c999fSMiguel Ojeda None 1667808c999fSMiguel Ojeda }; 1668808c999fSMiguel Ojeda 1669808c999fSMiguel Ojeda if turbofish.is_some() || input.peek(token::Paren) { 1670808c999fSMiguel Ojeda if let Member::Named(method) = member { 1671808c999fSMiguel Ojeda let content; 1672808c999fSMiguel Ojeda e = Expr::MethodCall(ExprMethodCall { 1673808c999fSMiguel Ojeda attrs: Vec::new(), 1674808c999fSMiguel Ojeda receiver: Box::new(e), 1675808c999fSMiguel Ojeda dot_token, 1676808c999fSMiguel Ojeda method, 1677808c999fSMiguel Ojeda turbofish, 1678808c999fSMiguel Ojeda paren_token: parenthesized!(content in input), 1679808c999fSMiguel Ojeda args: content.parse_terminated(Expr::parse, Token![,])?, 1680808c999fSMiguel Ojeda }); 1681808c999fSMiguel Ojeda continue; 1682808c999fSMiguel Ojeda } 1683808c999fSMiguel Ojeda } 1684808c999fSMiguel Ojeda 1685808c999fSMiguel Ojeda e = Expr::Field(ExprField { 1686808c999fSMiguel Ojeda attrs: Vec::new(), 1687808c999fSMiguel Ojeda base: Box::new(e), 1688808c999fSMiguel Ojeda dot_token, 1689808c999fSMiguel Ojeda member, 1690808c999fSMiguel Ojeda }); 1691808c999fSMiguel Ojeda } else if input.peek(token::Bracket) { 1692808c999fSMiguel Ojeda let content; 1693808c999fSMiguel Ojeda e = Expr::Index(ExprIndex { 1694808c999fSMiguel Ojeda attrs: Vec::new(), 1695808c999fSMiguel Ojeda expr: Box::new(e), 1696808c999fSMiguel Ojeda bracket_token: bracketed!(content in input), 1697808c999fSMiguel Ojeda index: content.parse()?, 1698808c999fSMiguel Ojeda }); 1699808c999fSMiguel Ojeda } else if input.peek(Token![?]) 1700808c999fSMiguel Ojeda && match e { 1701808c999fSMiguel Ojeda Expr::Range(_) => false, 1702808c999fSMiguel Ojeda _ => true, 1703808c999fSMiguel Ojeda } 1704808c999fSMiguel Ojeda { 1705808c999fSMiguel Ojeda e = Expr::Try(ExprTry { 1706808c999fSMiguel Ojeda attrs: Vec::new(), 1707808c999fSMiguel Ojeda expr: Box::new(e), 1708808c999fSMiguel Ojeda question_token: input.parse()?, 1709808c999fSMiguel Ojeda }); 1710808c999fSMiguel Ojeda } else { 1711808c999fSMiguel Ojeda break; 1712808c999fSMiguel Ojeda } 1713808c999fSMiguel Ojeda } 1714808c999fSMiguel Ojeda Ok(e) 1715808c999fSMiguel Ojeda } 1716808c999fSMiguel Ojeda 1717808c999fSMiguel Ojeda #[cfg(not(feature = "full"))] trailer_expr(input: ParseStream) -> Result<Expr>1718808c999fSMiguel Ojeda fn trailer_expr(input: ParseStream) -> Result<Expr> { 1719808c999fSMiguel Ojeda let mut e = atom_expr(input)?; 1720808c999fSMiguel Ojeda 1721808c999fSMiguel Ojeda loop { 1722808c999fSMiguel Ojeda if input.peek(token::Paren) { 1723808c999fSMiguel Ojeda let content; 1724808c999fSMiguel Ojeda e = Expr::Call(ExprCall { 1725808c999fSMiguel Ojeda attrs: Vec::new(), 1726808c999fSMiguel Ojeda func: Box::new(e), 1727808c999fSMiguel Ojeda paren_token: parenthesized!(content in input), 1728808c999fSMiguel Ojeda args: content.parse_terminated(Expr::parse, Token![,])?, 1729808c999fSMiguel Ojeda }); 1730808c999fSMiguel Ojeda } else if input.peek(Token![.]) 1731808c999fSMiguel Ojeda && !input.peek(Token![..]) 1732808c999fSMiguel Ojeda && !input.peek2(Token![await]) 1733808c999fSMiguel Ojeda { 1734808c999fSMiguel Ojeda let mut dot_token: Token![.] = input.parse()?; 1735808c999fSMiguel Ojeda 1736808c999fSMiguel Ojeda let float_token: Option<LitFloat> = input.parse()?; 1737808c999fSMiguel Ojeda if let Some(float_token) = float_token { 1738808c999fSMiguel Ojeda if multi_index(&mut e, &mut dot_token, float_token)? { 1739808c999fSMiguel Ojeda continue; 1740808c999fSMiguel Ojeda } 1741808c999fSMiguel Ojeda } 1742808c999fSMiguel Ojeda 1743808c999fSMiguel Ojeda let member: Member = input.parse()?; 1744808c999fSMiguel Ojeda let turbofish = if member.is_named() && input.peek(Token![::]) { 1745808c999fSMiguel Ojeda let colon2_token: Token![::] = input.parse()?; 1746808c999fSMiguel Ojeda let turbofish = 1747808c999fSMiguel Ojeda AngleBracketedGenericArguments::do_parse(Some(colon2_token), input)?; 1748808c999fSMiguel Ojeda Some(turbofish) 1749808c999fSMiguel Ojeda } else { 1750808c999fSMiguel Ojeda None 1751808c999fSMiguel Ojeda }; 1752808c999fSMiguel Ojeda 1753808c999fSMiguel Ojeda if turbofish.is_some() || input.peek(token::Paren) { 1754808c999fSMiguel Ojeda if let Member::Named(method) = member { 1755808c999fSMiguel Ojeda let content; 1756808c999fSMiguel Ojeda e = Expr::MethodCall(ExprMethodCall { 1757808c999fSMiguel Ojeda attrs: Vec::new(), 1758808c999fSMiguel Ojeda receiver: Box::new(e), 1759808c999fSMiguel Ojeda dot_token, 1760808c999fSMiguel Ojeda method, 1761808c999fSMiguel Ojeda turbofish, 1762808c999fSMiguel Ojeda paren_token: parenthesized!(content in input), 1763808c999fSMiguel Ojeda args: content.parse_terminated(Expr::parse, Token![,])?, 1764808c999fSMiguel Ojeda }); 1765808c999fSMiguel Ojeda continue; 1766808c999fSMiguel Ojeda } 1767808c999fSMiguel Ojeda } 1768808c999fSMiguel Ojeda 1769808c999fSMiguel Ojeda e = Expr::Field(ExprField { 1770808c999fSMiguel Ojeda attrs: Vec::new(), 1771808c999fSMiguel Ojeda base: Box::new(e), 1772808c999fSMiguel Ojeda dot_token, 1773808c999fSMiguel Ojeda member, 1774808c999fSMiguel Ojeda }); 1775808c999fSMiguel Ojeda } else if input.peek(token::Bracket) { 1776808c999fSMiguel Ojeda let content; 1777808c999fSMiguel Ojeda e = Expr::Index(ExprIndex { 1778808c999fSMiguel Ojeda attrs: Vec::new(), 1779808c999fSMiguel Ojeda expr: Box::new(e), 1780808c999fSMiguel Ojeda bracket_token: bracketed!(content in input), 1781808c999fSMiguel Ojeda index: content.parse()?, 1782808c999fSMiguel Ojeda }); 1783808c999fSMiguel Ojeda } else { 1784808c999fSMiguel Ojeda break; 1785808c999fSMiguel Ojeda } 1786808c999fSMiguel Ojeda } 1787808c999fSMiguel Ojeda 1788808c999fSMiguel Ojeda Ok(e) 1789808c999fSMiguel Ojeda } 1790808c999fSMiguel Ojeda 1791808c999fSMiguel Ojeda // Parse all atomic expressions which don't have to worry about precedence 1792808c999fSMiguel Ojeda // interactions, as they are fully contained. 1793808c999fSMiguel Ojeda #[cfg(feature = "full")] atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr>1794808c999fSMiguel Ojeda fn atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> { 1795808c999fSMiguel Ojeda if input.peek(token::Group) { 1796808c999fSMiguel Ojeda expr_group(input, allow_struct) 1797808c999fSMiguel Ojeda } else if input.peek(Lit) { 1798808c999fSMiguel Ojeda input.parse().map(Expr::Lit) 1799808c999fSMiguel Ojeda } else if input.peek(Token![async]) 1800808c999fSMiguel Ojeda && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace)) 1801808c999fSMiguel Ojeda { 1802808c999fSMiguel Ojeda input.parse().map(Expr::Async) 1803808c999fSMiguel Ojeda } else if input.peek(Token![try]) && input.peek2(token::Brace) { 1804808c999fSMiguel Ojeda input.parse().map(Expr::TryBlock) 1805808c999fSMiguel Ojeda } else if input.peek(Token![|]) 1806808c999fSMiguel Ojeda || input.peek(Token![move]) 1807808c999fSMiguel Ojeda || input.peek(Token![for]) 1808808c999fSMiguel Ojeda && generics::parsing::choose_generics_over_qpath_after_keyword(input) 1809808c999fSMiguel Ojeda || input.peek(Token![const]) && !input.peek2(token::Brace) 1810808c999fSMiguel Ojeda || input.peek(Token![static]) 1811808c999fSMiguel Ojeda || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move])) 1812808c999fSMiguel Ojeda { 1813808c999fSMiguel Ojeda expr_closure(input, allow_struct).map(Expr::Closure) 1814808c999fSMiguel Ojeda } else if token::parsing::peek_keyword(input.cursor(), "builtin") && input.peek2(Token![#]) 1815808c999fSMiguel Ojeda { 1816808c999fSMiguel Ojeda expr_builtin(input) 1817808c999fSMiguel Ojeda } else if input.peek(Ident) 1818808c999fSMiguel Ojeda || input.peek(Token![::]) 1819808c999fSMiguel Ojeda || input.peek(Token![<]) 1820808c999fSMiguel Ojeda || input.peek(Token![self]) 1821808c999fSMiguel Ojeda || input.peek(Token![Self]) 1822808c999fSMiguel Ojeda || input.peek(Token![super]) 1823808c999fSMiguel Ojeda || input.peek(Token![crate]) 1824808c999fSMiguel Ojeda || input.peek(Token![try]) && (input.peek2(Token![!]) || input.peek2(Token![::])) 1825808c999fSMiguel Ojeda { 1826808c999fSMiguel Ojeda path_or_macro_or_struct(input, allow_struct) 1827808c999fSMiguel Ojeda } else if input.peek(token::Paren) { 1828808c999fSMiguel Ojeda paren_or_tuple(input) 1829808c999fSMiguel Ojeda } else if input.peek(Token![break]) { 1830808c999fSMiguel Ojeda expr_break(input, allow_struct).map(Expr::Break) 1831808c999fSMiguel Ojeda } else if input.peek(Token![continue]) { 1832808c999fSMiguel Ojeda input.parse().map(Expr::Continue) 1833808c999fSMiguel Ojeda } else if input.peek(Token![return]) { 1834808c999fSMiguel Ojeda input.parse().map(Expr::Return) 1835808c999fSMiguel Ojeda } else if input.peek(Token![become]) { 1836808c999fSMiguel Ojeda expr_become(input) 1837808c999fSMiguel Ojeda } else if input.peek(token::Bracket) { 1838808c999fSMiguel Ojeda array_or_repeat(input) 1839808c999fSMiguel Ojeda } else if input.peek(Token![let]) { 1840808c999fSMiguel Ojeda expr_let(input, allow_struct).map(Expr::Let) 1841808c999fSMiguel Ojeda } else if input.peek(Token![if]) { 1842808c999fSMiguel Ojeda input.parse().map(Expr::If) 1843808c999fSMiguel Ojeda } else if input.peek(Token![while]) { 1844808c999fSMiguel Ojeda input.parse().map(Expr::While) 1845808c999fSMiguel Ojeda } else if input.peek(Token![for]) { 1846808c999fSMiguel Ojeda input.parse().map(Expr::ForLoop) 1847808c999fSMiguel Ojeda } else if input.peek(Token![loop]) { 1848808c999fSMiguel Ojeda input.parse().map(Expr::Loop) 1849808c999fSMiguel Ojeda } else if input.peek(Token![match]) { 1850808c999fSMiguel Ojeda input.parse().map(Expr::Match) 1851808c999fSMiguel Ojeda } else if input.peek(Token![yield]) { 1852808c999fSMiguel Ojeda input.parse().map(Expr::Yield) 1853808c999fSMiguel Ojeda } else if input.peek(Token![unsafe]) { 1854808c999fSMiguel Ojeda input.parse().map(Expr::Unsafe) 1855808c999fSMiguel Ojeda } else if input.peek(Token![const]) { 1856808c999fSMiguel Ojeda input.parse().map(Expr::Const) 1857808c999fSMiguel Ojeda } else if input.peek(token::Brace) { 1858808c999fSMiguel Ojeda input.parse().map(Expr::Block) 1859808c999fSMiguel Ojeda } else if input.peek(Token![..]) { 1860808c999fSMiguel Ojeda expr_range(input, allow_struct).map(Expr::Range) 1861808c999fSMiguel Ojeda } else if input.peek(Token![_]) { 1862808c999fSMiguel Ojeda input.parse().map(Expr::Infer) 1863808c999fSMiguel Ojeda } else if input.peek(Lifetime) { 1864808c999fSMiguel Ojeda atom_labeled(input) 1865808c999fSMiguel Ojeda } else { 1866808c999fSMiguel Ojeda Err(input.error("expected an expression")) 1867808c999fSMiguel Ojeda } 1868808c999fSMiguel Ojeda } 1869808c999fSMiguel Ojeda 1870808c999fSMiguel Ojeda #[cfg(feature = "full")] atom_labeled(input: ParseStream) -> Result<Expr>1871808c999fSMiguel Ojeda fn atom_labeled(input: ParseStream) -> Result<Expr> { 1872808c999fSMiguel Ojeda let the_label: Label = input.parse()?; 1873808c999fSMiguel Ojeda let mut expr = if input.peek(Token![while]) { 1874808c999fSMiguel Ojeda Expr::While(input.parse()?) 1875808c999fSMiguel Ojeda } else if input.peek(Token![for]) { 1876808c999fSMiguel Ojeda Expr::ForLoop(input.parse()?) 1877808c999fSMiguel Ojeda } else if input.peek(Token![loop]) { 1878808c999fSMiguel Ojeda Expr::Loop(input.parse()?) 1879808c999fSMiguel Ojeda } else if input.peek(token::Brace) { 1880808c999fSMiguel Ojeda Expr::Block(input.parse()?) 1881808c999fSMiguel Ojeda } else { 1882808c999fSMiguel Ojeda return Err(input.error("expected loop or block expression")); 1883808c999fSMiguel Ojeda }; 1884808c999fSMiguel Ojeda match &mut expr { 1885808c999fSMiguel Ojeda Expr::While(ExprWhile { label, .. }) 1886808c999fSMiguel Ojeda | Expr::ForLoop(ExprForLoop { label, .. }) 1887808c999fSMiguel Ojeda | Expr::Loop(ExprLoop { label, .. }) 1888808c999fSMiguel Ojeda | Expr::Block(ExprBlock { label, .. }) => *label = Some(the_label), 1889808c999fSMiguel Ojeda _ => unreachable!(), 1890808c999fSMiguel Ojeda } 1891808c999fSMiguel Ojeda Ok(expr) 1892808c999fSMiguel Ojeda } 1893808c999fSMiguel Ojeda 1894808c999fSMiguel Ojeda #[cfg(not(feature = "full"))] atom_expr(input: ParseStream) -> Result<Expr>1895808c999fSMiguel Ojeda fn atom_expr(input: ParseStream) -> Result<Expr> { 1896808c999fSMiguel Ojeda if input.peek(token::Group) { 1897808c999fSMiguel Ojeda expr_group(input) 1898808c999fSMiguel Ojeda } else if input.peek(Lit) { 1899808c999fSMiguel Ojeda input.parse().map(Expr::Lit) 1900808c999fSMiguel Ojeda } else if input.peek(token::Paren) { 1901808c999fSMiguel Ojeda paren_or_tuple(input) 1902808c999fSMiguel Ojeda } else if input.peek(Ident) 1903808c999fSMiguel Ojeda || input.peek(Token![::]) 1904808c999fSMiguel Ojeda || input.peek(Token![<]) 1905808c999fSMiguel Ojeda || input.peek(Token![self]) 1906808c999fSMiguel Ojeda || input.peek(Token![Self]) 1907808c999fSMiguel Ojeda || input.peek(Token![super]) 1908808c999fSMiguel Ojeda || input.peek(Token![crate]) 1909808c999fSMiguel Ojeda { 1910808c999fSMiguel Ojeda path_or_macro_or_struct(input) 1911808c999fSMiguel Ojeda } else if input.is_empty() { 1912808c999fSMiguel Ojeda Err(input.error("expected an expression")) 1913808c999fSMiguel Ojeda } else { 1914808c999fSMiguel Ojeda if input.peek(token::Brace) { 1915808c999fSMiguel Ojeda let scan = input.fork(); 1916808c999fSMiguel Ojeda let content; 1917808c999fSMiguel Ojeda braced!(content in scan); 1918808c999fSMiguel Ojeda if content.parse::<Expr>().is_ok() && content.is_empty() { 1919808c999fSMiguel Ojeda let expr_block = verbatim::between(input, &scan); 1920808c999fSMiguel Ojeda input.advance_to(&scan); 1921808c999fSMiguel Ojeda return Ok(Expr::Verbatim(expr_block)); 1922808c999fSMiguel Ojeda } 1923808c999fSMiguel Ojeda } 1924808c999fSMiguel Ojeda Err(input.error("unsupported expression; enable syn's features=[\"full\"]")) 1925808c999fSMiguel Ojeda } 1926808c999fSMiguel Ojeda } 1927808c999fSMiguel Ojeda 1928808c999fSMiguel Ojeda #[cfg(feature = "full")] expr_builtin(input: ParseStream) -> Result<Expr>1929808c999fSMiguel Ojeda fn expr_builtin(input: ParseStream) -> Result<Expr> { 1930808c999fSMiguel Ojeda let begin = input.fork(); 1931808c999fSMiguel Ojeda 1932808c999fSMiguel Ojeda token::parsing::keyword(input, "builtin")?; 1933808c999fSMiguel Ojeda input.parse::<Token![#]>()?; 1934808c999fSMiguel Ojeda input.parse::<Ident>()?; 1935808c999fSMiguel Ojeda 1936808c999fSMiguel Ojeda let args; 1937808c999fSMiguel Ojeda parenthesized!(args in input); 1938808c999fSMiguel Ojeda args.parse::<TokenStream>()?; 1939808c999fSMiguel Ojeda 1940808c999fSMiguel Ojeda Ok(Expr::Verbatim(verbatim::between(&begin, input))) 1941808c999fSMiguel Ojeda } 1942808c999fSMiguel Ojeda path_or_macro_or_struct( input: ParseStream, #[cfg(feature = "full")] allow_struct: AllowStruct, ) -> Result<Expr>1943808c999fSMiguel Ojeda fn path_or_macro_or_struct( 1944808c999fSMiguel Ojeda input: ParseStream, 1945808c999fSMiguel Ojeda #[cfg(feature = "full")] allow_struct: AllowStruct, 1946808c999fSMiguel Ojeda ) -> Result<Expr> { 1947808c999fSMiguel Ojeda let expr_style = true; 1948808c999fSMiguel Ojeda let (qself, path) = path::parsing::qpath(input, expr_style)?; 1949808c999fSMiguel Ojeda rest_of_path_or_macro_or_struct( 1950808c999fSMiguel Ojeda qself, 1951808c999fSMiguel Ojeda path, 1952808c999fSMiguel Ojeda input, 1953808c999fSMiguel Ojeda #[cfg(feature = "full")] 1954808c999fSMiguel Ojeda allow_struct, 1955808c999fSMiguel Ojeda ) 1956808c999fSMiguel Ojeda } 1957808c999fSMiguel Ojeda rest_of_path_or_macro_or_struct( qself: Option<QSelf>, path: Path, input: ParseStream, #[cfg(feature = "full")] allow_struct: AllowStruct, ) -> Result<Expr>1958808c999fSMiguel Ojeda fn rest_of_path_or_macro_or_struct( 1959808c999fSMiguel Ojeda qself: Option<QSelf>, 1960808c999fSMiguel Ojeda path: Path, 1961808c999fSMiguel Ojeda input: ParseStream, 1962808c999fSMiguel Ojeda #[cfg(feature = "full")] allow_struct: AllowStruct, 1963808c999fSMiguel Ojeda ) -> Result<Expr> { 1964808c999fSMiguel Ojeda if qself.is_none() 1965808c999fSMiguel Ojeda && input.peek(Token![!]) 1966808c999fSMiguel Ojeda && !input.peek(Token![!=]) 1967808c999fSMiguel Ojeda && path.is_mod_style() 1968808c999fSMiguel Ojeda { 1969808c999fSMiguel Ojeda let bang_token: Token![!] = input.parse()?; 1970808c999fSMiguel Ojeda let (delimiter, tokens) = mac::parse_delimiter(input)?; 1971808c999fSMiguel Ojeda return Ok(Expr::Macro(ExprMacro { 1972808c999fSMiguel Ojeda attrs: Vec::new(), 1973808c999fSMiguel Ojeda mac: Macro { 1974808c999fSMiguel Ojeda path, 1975808c999fSMiguel Ojeda bang_token, 1976808c999fSMiguel Ojeda delimiter, 1977808c999fSMiguel Ojeda tokens, 1978808c999fSMiguel Ojeda }, 1979808c999fSMiguel Ojeda })); 1980808c999fSMiguel Ojeda } 1981808c999fSMiguel Ojeda 1982808c999fSMiguel Ojeda #[cfg(not(feature = "full"))] 1983808c999fSMiguel Ojeda let allow_struct = (true,); 1984808c999fSMiguel Ojeda if allow_struct.0 && input.peek(token::Brace) { 1985808c999fSMiguel Ojeda return expr_struct_helper(input, qself, path).map(Expr::Struct); 1986808c999fSMiguel Ojeda } 1987808c999fSMiguel Ojeda 1988808c999fSMiguel Ojeda Ok(Expr::Path(ExprPath { 1989808c999fSMiguel Ojeda attrs: Vec::new(), 1990808c999fSMiguel Ojeda qself, 1991808c999fSMiguel Ojeda path, 1992808c999fSMiguel Ojeda })) 1993808c999fSMiguel Ojeda } 1994808c999fSMiguel Ojeda 1995808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 1996808c999fSMiguel Ojeda impl Parse for ExprMacro { parse(input: ParseStream) -> Result<Self>1997808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 1998808c999fSMiguel Ojeda Ok(ExprMacro { 1999808c999fSMiguel Ojeda attrs: Vec::new(), 2000808c999fSMiguel Ojeda mac: input.parse()?, 2001808c999fSMiguel Ojeda }) 2002808c999fSMiguel Ojeda } 2003808c999fSMiguel Ojeda } 2004808c999fSMiguel Ojeda paren_or_tuple(input: ParseStream) -> Result<Expr>2005808c999fSMiguel Ojeda fn paren_or_tuple(input: ParseStream) -> Result<Expr> { 2006808c999fSMiguel Ojeda let content; 2007808c999fSMiguel Ojeda let paren_token = parenthesized!(content in input); 2008808c999fSMiguel Ojeda if content.is_empty() { 2009808c999fSMiguel Ojeda return Ok(Expr::Tuple(ExprTuple { 2010808c999fSMiguel Ojeda attrs: Vec::new(), 2011808c999fSMiguel Ojeda paren_token, 2012808c999fSMiguel Ojeda elems: Punctuated::new(), 2013808c999fSMiguel Ojeda })); 2014808c999fSMiguel Ojeda } 2015808c999fSMiguel Ojeda 2016808c999fSMiguel Ojeda let first: Expr = content.parse()?; 2017808c999fSMiguel Ojeda if content.is_empty() { 2018808c999fSMiguel Ojeda return Ok(Expr::Paren(ExprParen { 2019808c999fSMiguel Ojeda attrs: Vec::new(), 2020808c999fSMiguel Ojeda paren_token, 2021808c999fSMiguel Ojeda expr: Box::new(first), 2022808c999fSMiguel Ojeda })); 2023808c999fSMiguel Ojeda } 2024808c999fSMiguel Ojeda 2025808c999fSMiguel Ojeda let mut elems = Punctuated::new(); 2026808c999fSMiguel Ojeda elems.push_value(first); 2027808c999fSMiguel Ojeda while !content.is_empty() { 2028808c999fSMiguel Ojeda let punct = content.parse()?; 2029808c999fSMiguel Ojeda elems.push_punct(punct); 2030808c999fSMiguel Ojeda if content.is_empty() { 2031808c999fSMiguel Ojeda break; 2032808c999fSMiguel Ojeda } 2033808c999fSMiguel Ojeda let value = content.parse()?; 2034808c999fSMiguel Ojeda elems.push_value(value); 2035808c999fSMiguel Ojeda } 2036808c999fSMiguel Ojeda Ok(Expr::Tuple(ExprTuple { 2037808c999fSMiguel Ojeda attrs: Vec::new(), 2038808c999fSMiguel Ojeda paren_token, 2039808c999fSMiguel Ojeda elems, 2040808c999fSMiguel Ojeda })) 2041808c999fSMiguel Ojeda } 2042808c999fSMiguel Ojeda 2043808c999fSMiguel Ojeda #[cfg(feature = "full")] array_or_repeat(input: ParseStream) -> Result<Expr>2044808c999fSMiguel Ojeda fn array_or_repeat(input: ParseStream) -> Result<Expr> { 2045808c999fSMiguel Ojeda let content; 2046808c999fSMiguel Ojeda let bracket_token = bracketed!(content in input); 2047808c999fSMiguel Ojeda if content.is_empty() { 2048808c999fSMiguel Ojeda return Ok(Expr::Array(ExprArray { 2049808c999fSMiguel Ojeda attrs: Vec::new(), 2050808c999fSMiguel Ojeda bracket_token, 2051808c999fSMiguel Ojeda elems: Punctuated::new(), 2052808c999fSMiguel Ojeda })); 2053808c999fSMiguel Ojeda } 2054808c999fSMiguel Ojeda 2055808c999fSMiguel Ojeda let first: Expr = content.parse()?; 2056808c999fSMiguel Ojeda if content.is_empty() || content.peek(Token![,]) { 2057808c999fSMiguel Ojeda let mut elems = Punctuated::new(); 2058808c999fSMiguel Ojeda elems.push_value(first); 2059808c999fSMiguel Ojeda while !content.is_empty() { 2060808c999fSMiguel Ojeda let punct = content.parse()?; 2061808c999fSMiguel Ojeda elems.push_punct(punct); 2062808c999fSMiguel Ojeda if content.is_empty() { 2063808c999fSMiguel Ojeda break; 2064808c999fSMiguel Ojeda } 2065808c999fSMiguel Ojeda let value = content.parse()?; 2066808c999fSMiguel Ojeda elems.push_value(value); 2067808c999fSMiguel Ojeda } 2068808c999fSMiguel Ojeda Ok(Expr::Array(ExprArray { 2069808c999fSMiguel Ojeda attrs: Vec::new(), 2070808c999fSMiguel Ojeda bracket_token, 2071808c999fSMiguel Ojeda elems, 2072808c999fSMiguel Ojeda })) 2073808c999fSMiguel Ojeda } else if content.peek(Token![;]) { 2074808c999fSMiguel Ojeda let semi_token: Token![;] = content.parse()?; 2075808c999fSMiguel Ojeda let len: Expr = content.parse()?; 2076808c999fSMiguel Ojeda Ok(Expr::Repeat(ExprRepeat { 2077808c999fSMiguel Ojeda attrs: Vec::new(), 2078808c999fSMiguel Ojeda bracket_token, 2079808c999fSMiguel Ojeda expr: Box::new(first), 2080808c999fSMiguel Ojeda semi_token, 2081808c999fSMiguel Ojeda len: Box::new(len), 2082808c999fSMiguel Ojeda })) 2083808c999fSMiguel Ojeda } else { 2084808c999fSMiguel Ojeda Err(content.error("expected `,` or `;`")) 2085808c999fSMiguel Ojeda } 2086808c999fSMiguel Ojeda } 2087808c999fSMiguel Ojeda 2088808c999fSMiguel Ojeda #[cfg(feature = "full")] 2089808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2090808c999fSMiguel Ojeda impl Parse for ExprArray { parse(input: ParseStream) -> Result<Self>2091808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2092808c999fSMiguel Ojeda let content; 2093808c999fSMiguel Ojeda let bracket_token = bracketed!(content in input); 2094808c999fSMiguel Ojeda let mut elems = Punctuated::new(); 2095808c999fSMiguel Ojeda 2096808c999fSMiguel Ojeda while !content.is_empty() { 2097808c999fSMiguel Ojeda let first: Expr = content.parse()?; 2098808c999fSMiguel Ojeda elems.push_value(first); 2099808c999fSMiguel Ojeda if content.is_empty() { 2100808c999fSMiguel Ojeda break; 2101808c999fSMiguel Ojeda } 2102808c999fSMiguel Ojeda let punct = content.parse()?; 2103808c999fSMiguel Ojeda elems.push_punct(punct); 2104808c999fSMiguel Ojeda } 2105808c999fSMiguel Ojeda 2106808c999fSMiguel Ojeda Ok(ExprArray { 2107808c999fSMiguel Ojeda attrs: Vec::new(), 2108808c999fSMiguel Ojeda bracket_token, 2109808c999fSMiguel Ojeda elems, 2110808c999fSMiguel Ojeda }) 2111808c999fSMiguel Ojeda } 2112808c999fSMiguel Ojeda } 2113808c999fSMiguel Ojeda 2114808c999fSMiguel Ojeda #[cfg(feature = "full")] 2115808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2116808c999fSMiguel Ojeda impl Parse for ExprRepeat { parse(input: ParseStream) -> Result<Self>2117808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2118808c999fSMiguel Ojeda let content; 2119808c999fSMiguel Ojeda Ok(ExprRepeat { 2120808c999fSMiguel Ojeda bracket_token: bracketed!(content in input), 2121808c999fSMiguel Ojeda attrs: Vec::new(), 2122808c999fSMiguel Ojeda expr: content.parse()?, 2123808c999fSMiguel Ojeda semi_token: content.parse()?, 2124808c999fSMiguel Ojeda len: content.parse()?, 2125808c999fSMiguel Ojeda }) 2126808c999fSMiguel Ojeda } 2127808c999fSMiguel Ojeda } 2128808c999fSMiguel Ojeda 2129808c999fSMiguel Ojeda #[cfg(feature = "full")] continue_parsing_early(mut expr: &Expr) -> bool2130808c999fSMiguel Ojeda fn continue_parsing_early(mut expr: &Expr) -> bool { 2131808c999fSMiguel Ojeda while let Expr::Group(group) = expr { 2132808c999fSMiguel Ojeda expr = &group.expr; 2133808c999fSMiguel Ojeda } 2134808c999fSMiguel Ojeda match expr { 2135808c999fSMiguel Ojeda Expr::If(_) 2136808c999fSMiguel Ojeda | Expr::While(_) 2137808c999fSMiguel Ojeda | Expr::ForLoop(_) 2138808c999fSMiguel Ojeda | Expr::Loop(_) 2139808c999fSMiguel Ojeda | Expr::Match(_) 2140808c999fSMiguel Ojeda | Expr::TryBlock(_) 2141808c999fSMiguel Ojeda | Expr::Unsafe(_) 2142808c999fSMiguel Ojeda | Expr::Const(_) 2143808c999fSMiguel Ojeda | Expr::Block(_) => false, 2144808c999fSMiguel Ojeda _ => true, 2145808c999fSMiguel Ojeda } 2146808c999fSMiguel Ojeda } 2147808c999fSMiguel Ojeda 2148808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2149808c999fSMiguel Ojeda impl Parse for ExprLit { parse(input: ParseStream) -> Result<Self>2150808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2151808c999fSMiguel Ojeda Ok(ExprLit { 2152808c999fSMiguel Ojeda attrs: Vec::new(), 2153808c999fSMiguel Ojeda lit: input.parse()?, 2154808c999fSMiguel Ojeda }) 2155808c999fSMiguel Ojeda } 2156808c999fSMiguel Ojeda } 2157808c999fSMiguel Ojeda expr_group( input: ParseStream, #[cfg(feature = "full")] allow_struct: AllowStruct, ) -> Result<Expr>2158808c999fSMiguel Ojeda fn expr_group( 2159808c999fSMiguel Ojeda input: ParseStream, 2160808c999fSMiguel Ojeda #[cfg(feature = "full")] allow_struct: AllowStruct, 2161808c999fSMiguel Ojeda ) -> Result<Expr> { 2162808c999fSMiguel Ojeda let group = crate::group::parse_group(input)?; 2163808c999fSMiguel Ojeda let mut inner: Expr = group.content.parse()?; 2164808c999fSMiguel Ojeda 2165808c999fSMiguel Ojeda match inner { 2166808c999fSMiguel Ojeda Expr::Path(mut expr) if expr.attrs.is_empty() => { 2167808c999fSMiguel Ojeda let grouped_len = expr.path.segments.len(); 2168808c999fSMiguel Ojeda Path::parse_rest(input, &mut expr.path, true)?; 2169808c999fSMiguel Ojeda match rest_of_path_or_macro_or_struct( 2170808c999fSMiguel Ojeda expr.qself, 2171808c999fSMiguel Ojeda expr.path, 2172808c999fSMiguel Ojeda input, 2173808c999fSMiguel Ojeda #[cfg(feature = "full")] 2174808c999fSMiguel Ojeda allow_struct, 2175808c999fSMiguel Ojeda )? { 2176808c999fSMiguel Ojeda Expr::Path(expr) if expr.path.segments.len() == grouped_len => { 2177808c999fSMiguel Ojeda inner = Expr::Path(expr); 2178808c999fSMiguel Ojeda } 2179808c999fSMiguel Ojeda extended => return Ok(extended), 2180808c999fSMiguel Ojeda } 2181808c999fSMiguel Ojeda } 2182808c999fSMiguel Ojeda _ => {} 2183808c999fSMiguel Ojeda } 2184808c999fSMiguel Ojeda 2185808c999fSMiguel Ojeda Ok(Expr::Group(ExprGroup { 2186808c999fSMiguel Ojeda attrs: Vec::new(), 2187808c999fSMiguel Ojeda group_token: group.token, 2188808c999fSMiguel Ojeda expr: Box::new(inner), 2189808c999fSMiguel Ojeda })) 2190808c999fSMiguel Ojeda } 2191808c999fSMiguel Ojeda 2192808c999fSMiguel Ojeda #[cfg(feature = "full")] 2193808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2194808c999fSMiguel Ojeda impl Parse for ExprParen { parse(input: ParseStream) -> Result<Self>2195808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2196808c999fSMiguel Ojeda let content; 2197808c999fSMiguel Ojeda Ok(ExprParen { 2198808c999fSMiguel Ojeda attrs: Vec::new(), 2199808c999fSMiguel Ojeda paren_token: parenthesized!(content in input), 2200808c999fSMiguel Ojeda expr: content.parse()?, 2201808c999fSMiguel Ojeda }) 2202808c999fSMiguel Ojeda } 2203808c999fSMiguel Ojeda } 2204808c999fSMiguel Ojeda 2205808c999fSMiguel Ojeda #[cfg(feature = "full")] 2206808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2207808c999fSMiguel Ojeda impl Parse for ExprLet { parse(input: ParseStream) -> Result<Self>2208808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2209808c999fSMiguel Ojeda let allow_struct = AllowStruct(true); 2210808c999fSMiguel Ojeda expr_let(input, allow_struct) 2211808c999fSMiguel Ojeda } 2212808c999fSMiguel Ojeda } 2213808c999fSMiguel Ojeda 2214808c999fSMiguel Ojeda #[cfg(feature = "full")] expr_let(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprLet>2215808c999fSMiguel Ojeda fn expr_let(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprLet> { 2216808c999fSMiguel Ojeda Ok(ExprLet { 2217808c999fSMiguel Ojeda attrs: Vec::new(), 2218808c999fSMiguel Ojeda let_token: input.parse()?, 2219808c999fSMiguel Ojeda pat: Box::new(Pat::parse_multi_with_leading_vert(input)?), 2220808c999fSMiguel Ojeda eq_token: input.parse()?, 2221808c999fSMiguel Ojeda expr: Box::new({ 2222808c999fSMiguel Ojeda let lhs = unary_expr(input, allow_struct)?; 2223808c999fSMiguel Ojeda parse_expr(input, lhs, allow_struct, Precedence::Compare)? 2224808c999fSMiguel Ojeda }), 2225808c999fSMiguel Ojeda }) 2226808c999fSMiguel Ojeda } 2227808c999fSMiguel Ojeda 2228808c999fSMiguel Ojeda #[cfg(feature = "full")] 2229808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2230808c999fSMiguel Ojeda impl Parse for ExprIf { parse(input: ParseStream) -> Result<Self>2231808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2232808c999fSMiguel Ojeda let attrs = input.call(Attribute::parse_outer)?; 2233808c999fSMiguel Ojeda 2234808c999fSMiguel Ojeda let mut clauses = Vec::new(); 2235808c999fSMiguel Ojeda let mut expr; 2236808c999fSMiguel Ojeda loop { 2237808c999fSMiguel Ojeda let if_token: Token![if] = input.parse()?; 2238808c999fSMiguel Ojeda let cond = input.call(Expr::parse_without_eager_brace)?; 2239808c999fSMiguel Ojeda let then_branch: Block = input.parse()?; 2240808c999fSMiguel Ojeda 2241808c999fSMiguel Ojeda expr = ExprIf { 2242808c999fSMiguel Ojeda attrs: Vec::new(), 2243808c999fSMiguel Ojeda if_token, 2244808c999fSMiguel Ojeda cond: Box::new(cond), 2245808c999fSMiguel Ojeda then_branch, 2246808c999fSMiguel Ojeda else_branch: None, 2247808c999fSMiguel Ojeda }; 2248808c999fSMiguel Ojeda 2249808c999fSMiguel Ojeda if !input.peek(Token![else]) { 2250808c999fSMiguel Ojeda break; 2251808c999fSMiguel Ojeda } 2252808c999fSMiguel Ojeda 2253808c999fSMiguel Ojeda let else_token: Token![else] = input.parse()?; 2254808c999fSMiguel Ojeda let lookahead = input.lookahead1(); 2255808c999fSMiguel Ojeda if lookahead.peek(Token![if]) { 2256808c999fSMiguel Ojeda expr.else_branch = Some((else_token, Box::new(Expr::PLACEHOLDER))); 2257808c999fSMiguel Ojeda clauses.push(expr); 2258808c999fSMiguel Ojeda } else if lookahead.peek(token::Brace) { 2259808c999fSMiguel Ojeda expr.else_branch = Some(( 2260808c999fSMiguel Ojeda else_token, 2261808c999fSMiguel Ojeda Box::new(Expr::Block(ExprBlock { 2262808c999fSMiguel Ojeda attrs: Vec::new(), 2263808c999fSMiguel Ojeda label: None, 2264808c999fSMiguel Ojeda block: input.parse()?, 2265808c999fSMiguel Ojeda })), 2266808c999fSMiguel Ojeda )); 2267808c999fSMiguel Ojeda break; 2268808c999fSMiguel Ojeda } else { 2269808c999fSMiguel Ojeda return Err(lookahead.error()); 2270808c999fSMiguel Ojeda } 2271808c999fSMiguel Ojeda } 2272808c999fSMiguel Ojeda 2273808c999fSMiguel Ojeda while let Some(mut prev) = clauses.pop() { 2274808c999fSMiguel Ojeda *prev.else_branch.as_mut().unwrap().1 = Expr::If(expr); 2275808c999fSMiguel Ojeda expr = prev; 2276808c999fSMiguel Ojeda } 2277808c999fSMiguel Ojeda expr.attrs = attrs; 2278808c999fSMiguel Ojeda Ok(expr) 2279808c999fSMiguel Ojeda } 2280808c999fSMiguel Ojeda } 2281808c999fSMiguel Ojeda 2282808c999fSMiguel Ojeda #[cfg(feature = "full")] 2283808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2284808c999fSMiguel Ojeda impl Parse for ExprInfer { parse(input: ParseStream) -> Result<Self>2285808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2286808c999fSMiguel Ojeda Ok(ExprInfer { 2287808c999fSMiguel Ojeda attrs: input.call(Attribute::parse_outer)?, 2288808c999fSMiguel Ojeda underscore_token: input.parse()?, 2289808c999fSMiguel Ojeda }) 2290808c999fSMiguel Ojeda } 2291808c999fSMiguel Ojeda } 2292808c999fSMiguel Ojeda 2293808c999fSMiguel Ojeda #[cfg(feature = "full")] 2294808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2295808c999fSMiguel Ojeda impl Parse for ExprForLoop { parse(input: ParseStream) -> Result<Self>2296808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2297808c999fSMiguel Ojeda let mut attrs = input.call(Attribute::parse_outer)?; 2298808c999fSMiguel Ojeda let label: Option<Label> = input.parse()?; 2299808c999fSMiguel Ojeda let for_token: Token![for] = input.parse()?; 2300808c999fSMiguel Ojeda 2301808c999fSMiguel Ojeda let pat = Pat::parse_multi_with_leading_vert(input)?; 2302808c999fSMiguel Ojeda 2303808c999fSMiguel Ojeda let in_token: Token![in] = input.parse()?; 2304808c999fSMiguel Ojeda let expr: Expr = input.call(Expr::parse_without_eager_brace)?; 2305808c999fSMiguel Ojeda 2306808c999fSMiguel Ojeda let content; 2307808c999fSMiguel Ojeda let brace_token = braced!(content in input); 2308808c999fSMiguel Ojeda attr::parsing::parse_inner(&content, &mut attrs)?; 2309808c999fSMiguel Ojeda let stmts = content.call(Block::parse_within)?; 2310808c999fSMiguel Ojeda 2311808c999fSMiguel Ojeda Ok(ExprForLoop { 2312808c999fSMiguel Ojeda attrs, 2313808c999fSMiguel Ojeda label, 2314808c999fSMiguel Ojeda for_token, 2315808c999fSMiguel Ojeda pat: Box::new(pat), 2316808c999fSMiguel Ojeda in_token, 2317808c999fSMiguel Ojeda expr: Box::new(expr), 2318808c999fSMiguel Ojeda body: Block { brace_token, stmts }, 2319808c999fSMiguel Ojeda }) 2320808c999fSMiguel Ojeda } 2321808c999fSMiguel Ojeda } 2322808c999fSMiguel Ojeda 2323808c999fSMiguel Ojeda #[cfg(feature = "full")] 2324808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2325808c999fSMiguel Ojeda impl Parse for ExprLoop { parse(input: ParseStream) -> Result<Self>2326808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2327808c999fSMiguel Ojeda let mut attrs = input.call(Attribute::parse_outer)?; 2328808c999fSMiguel Ojeda let label: Option<Label> = input.parse()?; 2329808c999fSMiguel Ojeda let loop_token: Token![loop] = input.parse()?; 2330808c999fSMiguel Ojeda 2331808c999fSMiguel Ojeda let content; 2332808c999fSMiguel Ojeda let brace_token = braced!(content in input); 2333808c999fSMiguel Ojeda attr::parsing::parse_inner(&content, &mut attrs)?; 2334808c999fSMiguel Ojeda let stmts = content.call(Block::parse_within)?; 2335808c999fSMiguel Ojeda 2336808c999fSMiguel Ojeda Ok(ExprLoop { 2337808c999fSMiguel Ojeda attrs, 2338808c999fSMiguel Ojeda label, 2339808c999fSMiguel Ojeda loop_token, 2340808c999fSMiguel Ojeda body: Block { brace_token, stmts }, 2341808c999fSMiguel Ojeda }) 2342808c999fSMiguel Ojeda } 2343808c999fSMiguel Ojeda } 2344808c999fSMiguel Ojeda 2345808c999fSMiguel Ojeda #[cfg(feature = "full")] 2346808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2347808c999fSMiguel Ojeda impl Parse for ExprMatch { parse(input: ParseStream) -> Result<Self>2348808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2349808c999fSMiguel Ojeda let mut attrs = input.call(Attribute::parse_outer)?; 2350808c999fSMiguel Ojeda let match_token: Token![match] = input.parse()?; 2351808c999fSMiguel Ojeda let expr = Expr::parse_without_eager_brace(input)?; 2352808c999fSMiguel Ojeda 2353808c999fSMiguel Ojeda let content; 2354808c999fSMiguel Ojeda let brace_token = braced!(content in input); 2355808c999fSMiguel Ojeda attr::parsing::parse_inner(&content, &mut attrs)?; 2356808c999fSMiguel Ojeda 2357808c999fSMiguel Ojeda let arms = Arm::parse_multiple(&content)?; 2358808c999fSMiguel Ojeda 2359808c999fSMiguel Ojeda Ok(ExprMatch { 2360808c999fSMiguel Ojeda attrs, 2361808c999fSMiguel Ojeda match_token, 2362808c999fSMiguel Ojeda expr: Box::new(expr), 2363808c999fSMiguel Ojeda brace_token, 2364808c999fSMiguel Ojeda arms, 2365808c999fSMiguel Ojeda }) 2366808c999fSMiguel Ojeda } 2367808c999fSMiguel Ojeda } 2368808c999fSMiguel Ojeda 2369808c999fSMiguel Ojeda macro_rules! impl_by_parsing_expr { 2370808c999fSMiguel Ojeda ( 2371808c999fSMiguel Ojeda $( 2372808c999fSMiguel Ojeda $expr_type:ty, $variant:ident, $msg:expr, 2373808c999fSMiguel Ojeda )* 2374808c999fSMiguel Ojeda ) => { 2375808c999fSMiguel Ojeda $( 2376808c999fSMiguel Ojeda #[cfg(all(feature = "full", feature = "printing"))] 2377808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2378808c999fSMiguel Ojeda impl Parse for $expr_type { 2379808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2380808c999fSMiguel Ojeda let mut expr: Expr = input.parse()?; 2381808c999fSMiguel Ojeda loop { 2382808c999fSMiguel Ojeda match expr { 2383808c999fSMiguel Ojeda Expr::$variant(inner) => return Ok(inner), 2384808c999fSMiguel Ojeda Expr::Group(next) => expr = *next.expr, 2385808c999fSMiguel Ojeda _ => return Err(Error::new_spanned(expr, $msg)), 2386808c999fSMiguel Ojeda } 2387808c999fSMiguel Ojeda } 2388808c999fSMiguel Ojeda } 2389808c999fSMiguel Ojeda } 2390808c999fSMiguel Ojeda )* 2391808c999fSMiguel Ojeda }; 2392808c999fSMiguel Ojeda } 2393808c999fSMiguel Ojeda 2394808c999fSMiguel Ojeda impl_by_parsing_expr! { 2395808c999fSMiguel Ojeda ExprAssign, Assign, "expected assignment expression", 2396808c999fSMiguel Ojeda ExprAwait, Await, "expected await expression", 2397808c999fSMiguel Ojeda ExprBinary, Binary, "expected binary operation", 2398808c999fSMiguel Ojeda ExprCall, Call, "expected function call expression", 2399808c999fSMiguel Ojeda ExprCast, Cast, "expected cast expression", 2400808c999fSMiguel Ojeda ExprField, Field, "expected struct field access", 2401808c999fSMiguel Ojeda ExprIndex, Index, "expected indexing expression", 2402808c999fSMiguel Ojeda ExprMethodCall, MethodCall, "expected method call expression", 2403808c999fSMiguel Ojeda ExprRange, Range, "expected range expression", 2404808c999fSMiguel Ojeda ExprTry, Try, "expected try expression", 2405808c999fSMiguel Ojeda ExprTuple, Tuple, "expected tuple expression", 2406808c999fSMiguel Ojeda } 2407808c999fSMiguel Ojeda 2408808c999fSMiguel Ojeda #[cfg(feature = "full")] 2409808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2410808c999fSMiguel Ojeda impl Parse for ExprUnary { parse(input: ParseStream) -> Result<Self>2411808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2412808c999fSMiguel Ojeda let attrs = Vec::new(); 2413808c999fSMiguel Ojeda let allow_struct = AllowStruct(true); 2414808c999fSMiguel Ojeda expr_unary(input, attrs, allow_struct) 2415808c999fSMiguel Ojeda } 2416808c999fSMiguel Ojeda } 2417808c999fSMiguel Ojeda 2418808c999fSMiguel Ojeda #[cfg(feature = "full")] expr_unary( input: ParseStream, attrs: Vec<Attribute>, allow_struct: AllowStruct, ) -> Result<ExprUnary>2419808c999fSMiguel Ojeda fn expr_unary( 2420808c999fSMiguel Ojeda input: ParseStream, 2421808c999fSMiguel Ojeda attrs: Vec<Attribute>, 2422808c999fSMiguel Ojeda allow_struct: AllowStruct, 2423808c999fSMiguel Ojeda ) -> Result<ExprUnary> { 2424808c999fSMiguel Ojeda Ok(ExprUnary { 2425808c999fSMiguel Ojeda attrs, 2426808c999fSMiguel Ojeda op: input.parse()?, 2427808c999fSMiguel Ojeda expr: Box::new(unary_expr(input, allow_struct)?), 2428808c999fSMiguel Ojeda }) 2429808c999fSMiguel Ojeda } 2430808c999fSMiguel Ojeda 2431808c999fSMiguel Ojeda #[cfg(feature = "full")] 2432808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2433808c999fSMiguel Ojeda impl Parse for ExprClosure { parse(input: ParseStream) -> Result<Self>2434808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2435808c999fSMiguel Ojeda let allow_struct = AllowStruct(true); 2436808c999fSMiguel Ojeda expr_closure(input, allow_struct) 2437808c999fSMiguel Ojeda } 2438808c999fSMiguel Ojeda } 2439808c999fSMiguel Ojeda 2440808c999fSMiguel Ojeda #[cfg(feature = "full")] 2441808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2442808c999fSMiguel Ojeda impl Parse for ExprRawAddr { parse(input: ParseStream) -> Result<Self>2443808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2444808c999fSMiguel Ojeda let allow_struct = AllowStruct(true); 2445808c999fSMiguel Ojeda Ok(ExprRawAddr { 2446808c999fSMiguel Ojeda attrs: Vec::new(), 2447808c999fSMiguel Ojeda and_token: input.parse()?, 2448808c999fSMiguel Ojeda raw: input.parse()?, 2449808c999fSMiguel Ojeda mutability: input.parse()?, 2450808c999fSMiguel Ojeda expr: Box::new(unary_expr(input, allow_struct)?), 2451808c999fSMiguel Ojeda }) 2452808c999fSMiguel Ojeda } 2453808c999fSMiguel Ojeda } 2454808c999fSMiguel Ojeda 2455808c999fSMiguel Ojeda #[cfg(feature = "full")] 2456808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2457808c999fSMiguel Ojeda impl Parse for ExprReference { parse(input: ParseStream) -> Result<Self>2458808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2459808c999fSMiguel Ojeda let allow_struct = AllowStruct(true); 2460808c999fSMiguel Ojeda Ok(ExprReference { 2461808c999fSMiguel Ojeda attrs: Vec::new(), 2462808c999fSMiguel Ojeda and_token: input.parse()?, 2463808c999fSMiguel Ojeda mutability: input.parse()?, 2464808c999fSMiguel Ojeda expr: Box::new(unary_expr(input, allow_struct)?), 2465808c999fSMiguel Ojeda }) 2466808c999fSMiguel Ojeda } 2467808c999fSMiguel Ojeda } 2468808c999fSMiguel Ojeda 2469808c999fSMiguel Ojeda #[cfg(feature = "full")] 2470808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2471808c999fSMiguel Ojeda impl Parse for ExprBreak { parse(input: ParseStream) -> Result<Self>2472808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2473808c999fSMiguel Ojeda let allow_struct = AllowStruct(true); 2474808c999fSMiguel Ojeda expr_break(input, allow_struct) 2475808c999fSMiguel Ojeda } 2476808c999fSMiguel Ojeda } 2477808c999fSMiguel Ojeda 2478808c999fSMiguel Ojeda #[cfg(feature = "full")] 2479808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2480808c999fSMiguel Ojeda impl Parse for ExprReturn { parse(input: ParseStream) -> Result<Self>2481808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2482808c999fSMiguel Ojeda Ok(ExprReturn { 2483808c999fSMiguel Ojeda attrs: Vec::new(), 2484808c999fSMiguel Ojeda return_token: input.parse()?, 2485808c999fSMiguel Ojeda expr: { 2486808c999fSMiguel Ojeda if Expr::peek(input) { 2487808c999fSMiguel Ojeda Some(input.parse()?) 2488808c999fSMiguel Ojeda } else { 2489808c999fSMiguel Ojeda None 2490808c999fSMiguel Ojeda } 2491808c999fSMiguel Ojeda }, 2492808c999fSMiguel Ojeda }) 2493808c999fSMiguel Ojeda } 2494808c999fSMiguel Ojeda } 2495808c999fSMiguel Ojeda 2496808c999fSMiguel Ojeda #[cfg(feature = "full")] expr_become(input: ParseStream) -> Result<Expr>2497808c999fSMiguel Ojeda fn expr_become(input: ParseStream) -> Result<Expr> { 2498808c999fSMiguel Ojeda let begin = input.fork(); 2499808c999fSMiguel Ojeda input.parse::<Token![become]>()?; 2500808c999fSMiguel Ojeda input.parse::<Expr>()?; 2501808c999fSMiguel Ojeda Ok(Expr::Verbatim(verbatim::between(&begin, input))) 2502808c999fSMiguel Ojeda } 2503808c999fSMiguel Ojeda 2504808c999fSMiguel Ojeda #[cfg(feature = "full")] 2505808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2506808c999fSMiguel Ojeda impl Parse for ExprTryBlock { parse(input: ParseStream) -> Result<Self>2507808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2508808c999fSMiguel Ojeda Ok(ExprTryBlock { 2509808c999fSMiguel Ojeda attrs: Vec::new(), 2510808c999fSMiguel Ojeda try_token: input.parse()?, 2511808c999fSMiguel Ojeda block: input.parse()?, 2512808c999fSMiguel Ojeda }) 2513808c999fSMiguel Ojeda } 2514808c999fSMiguel Ojeda } 2515808c999fSMiguel Ojeda 2516808c999fSMiguel Ojeda #[cfg(feature = "full")] 2517808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2518808c999fSMiguel Ojeda impl Parse for ExprYield { parse(input: ParseStream) -> Result<Self>2519808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2520808c999fSMiguel Ojeda Ok(ExprYield { 2521808c999fSMiguel Ojeda attrs: Vec::new(), 2522808c999fSMiguel Ojeda yield_token: input.parse()?, 2523808c999fSMiguel Ojeda expr: { 2524808c999fSMiguel Ojeda if Expr::peek(input) { 2525808c999fSMiguel Ojeda Some(input.parse()?) 2526808c999fSMiguel Ojeda } else { 2527808c999fSMiguel Ojeda None 2528808c999fSMiguel Ojeda } 2529808c999fSMiguel Ojeda }, 2530808c999fSMiguel Ojeda }) 2531808c999fSMiguel Ojeda } 2532808c999fSMiguel Ojeda } 2533808c999fSMiguel Ojeda 2534808c999fSMiguel Ojeda #[cfg(feature = "full")] expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure>2535808c999fSMiguel Ojeda fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> { 2536808c999fSMiguel Ojeda let lifetimes: Option<BoundLifetimes> = input.parse()?; 2537808c999fSMiguel Ojeda let constness: Option<Token![const]> = input.parse()?; 2538808c999fSMiguel Ojeda let movability: Option<Token![static]> = input.parse()?; 2539808c999fSMiguel Ojeda let asyncness: Option<Token![async]> = input.parse()?; 2540808c999fSMiguel Ojeda let capture: Option<Token![move]> = input.parse()?; 2541808c999fSMiguel Ojeda let or1_token: Token![|] = input.parse()?; 2542808c999fSMiguel Ojeda 2543808c999fSMiguel Ojeda let mut inputs = Punctuated::new(); 2544808c999fSMiguel Ojeda loop { 2545808c999fSMiguel Ojeda if input.peek(Token![|]) { 2546808c999fSMiguel Ojeda break; 2547808c999fSMiguel Ojeda } 2548808c999fSMiguel Ojeda let value = closure_arg(input)?; 2549808c999fSMiguel Ojeda inputs.push_value(value); 2550808c999fSMiguel Ojeda if input.peek(Token![|]) { 2551808c999fSMiguel Ojeda break; 2552808c999fSMiguel Ojeda } 2553808c999fSMiguel Ojeda let punct: Token![,] = input.parse()?; 2554808c999fSMiguel Ojeda inputs.push_punct(punct); 2555808c999fSMiguel Ojeda } 2556808c999fSMiguel Ojeda 2557808c999fSMiguel Ojeda let or2_token: Token![|] = input.parse()?; 2558808c999fSMiguel Ojeda 2559808c999fSMiguel Ojeda let (output, body) = if input.peek(Token![->]) { 2560808c999fSMiguel Ojeda let arrow_token: Token![->] = input.parse()?; 2561808c999fSMiguel Ojeda let ty: Type = input.parse()?; 2562808c999fSMiguel Ojeda let body: Block = input.parse()?; 2563808c999fSMiguel Ojeda let output = ReturnType::Type(arrow_token, Box::new(ty)); 2564808c999fSMiguel Ojeda let block = Expr::Block(ExprBlock { 2565808c999fSMiguel Ojeda attrs: Vec::new(), 2566808c999fSMiguel Ojeda label: None, 2567808c999fSMiguel Ojeda block: body, 2568808c999fSMiguel Ojeda }); 2569808c999fSMiguel Ojeda (output, block) 2570808c999fSMiguel Ojeda } else { 2571808c999fSMiguel Ojeda let body = ambiguous_expr(input, allow_struct)?; 2572808c999fSMiguel Ojeda (ReturnType::Default, body) 2573808c999fSMiguel Ojeda }; 2574808c999fSMiguel Ojeda 2575808c999fSMiguel Ojeda Ok(ExprClosure { 2576808c999fSMiguel Ojeda attrs: Vec::new(), 2577808c999fSMiguel Ojeda lifetimes, 2578808c999fSMiguel Ojeda constness, 2579808c999fSMiguel Ojeda movability, 2580808c999fSMiguel Ojeda asyncness, 2581808c999fSMiguel Ojeda capture, 2582808c999fSMiguel Ojeda or1_token, 2583808c999fSMiguel Ojeda inputs, 2584808c999fSMiguel Ojeda or2_token, 2585808c999fSMiguel Ojeda output, 2586808c999fSMiguel Ojeda body: Box::new(body), 2587808c999fSMiguel Ojeda }) 2588808c999fSMiguel Ojeda } 2589808c999fSMiguel Ojeda 2590808c999fSMiguel Ojeda #[cfg(feature = "full")] 2591808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2592808c999fSMiguel Ojeda impl Parse for ExprAsync { parse(input: ParseStream) -> Result<Self>2593808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2594808c999fSMiguel Ojeda Ok(ExprAsync { 2595808c999fSMiguel Ojeda attrs: Vec::new(), 2596808c999fSMiguel Ojeda async_token: input.parse()?, 2597808c999fSMiguel Ojeda capture: input.parse()?, 2598808c999fSMiguel Ojeda block: input.parse()?, 2599808c999fSMiguel Ojeda }) 2600808c999fSMiguel Ojeda } 2601808c999fSMiguel Ojeda } 2602808c999fSMiguel Ojeda 2603808c999fSMiguel Ojeda #[cfg(feature = "full")] closure_arg(input: ParseStream) -> Result<Pat>2604808c999fSMiguel Ojeda fn closure_arg(input: ParseStream) -> Result<Pat> { 2605808c999fSMiguel Ojeda let attrs = input.call(Attribute::parse_outer)?; 2606808c999fSMiguel Ojeda let mut pat = Pat::parse_single(input)?; 2607808c999fSMiguel Ojeda 2608808c999fSMiguel Ojeda if input.peek(Token![:]) { 2609808c999fSMiguel Ojeda Ok(Pat::Type(PatType { 2610808c999fSMiguel Ojeda attrs, 2611808c999fSMiguel Ojeda pat: Box::new(pat), 2612808c999fSMiguel Ojeda colon_token: input.parse()?, 2613808c999fSMiguel Ojeda ty: input.parse()?, 2614808c999fSMiguel Ojeda })) 2615808c999fSMiguel Ojeda } else { 2616808c999fSMiguel Ojeda match &mut pat { 2617808c999fSMiguel Ojeda Pat::Const(pat) => pat.attrs = attrs, 2618808c999fSMiguel Ojeda Pat::Ident(pat) => pat.attrs = attrs, 2619808c999fSMiguel Ojeda Pat::Lit(pat) => pat.attrs = attrs, 2620808c999fSMiguel Ojeda Pat::Macro(pat) => pat.attrs = attrs, 2621808c999fSMiguel Ojeda Pat::Or(pat) => pat.attrs = attrs, 2622808c999fSMiguel Ojeda Pat::Paren(pat) => pat.attrs = attrs, 2623808c999fSMiguel Ojeda Pat::Path(pat) => pat.attrs = attrs, 2624808c999fSMiguel Ojeda Pat::Range(pat) => pat.attrs = attrs, 2625808c999fSMiguel Ojeda Pat::Reference(pat) => pat.attrs = attrs, 2626808c999fSMiguel Ojeda Pat::Rest(pat) => pat.attrs = attrs, 2627808c999fSMiguel Ojeda Pat::Slice(pat) => pat.attrs = attrs, 2628808c999fSMiguel Ojeda Pat::Struct(pat) => pat.attrs = attrs, 2629808c999fSMiguel Ojeda Pat::Tuple(pat) => pat.attrs = attrs, 2630808c999fSMiguel Ojeda Pat::TupleStruct(pat) => pat.attrs = attrs, 2631808c999fSMiguel Ojeda Pat::Type(_) => unreachable!(), 2632808c999fSMiguel Ojeda Pat::Verbatim(_) => {} 2633808c999fSMiguel Ojeda Pat::Wild(pat) => pat.attrs = attrs, 2634808c999fSMiguel Ojeda } 2635808c999fSMiguel Ojeda Ok(pat) 2636808c999fSMiguel Ojeda } 2637808c999fSMiguel Ojeda } 2638808c999fSMiguel Ojeda 2639808c999fSMiguel Ojeda #[cfg(feature = "full")] 2640808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2641808c999fSMiguel Ojeda impl Parse for ExprWhile { parse(input: ParseStream) -> Result<Self>2642808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2643808c999fSMiguel Ojeda let mut attrs = input.call(Attribute::parse_outer)?; 2644808c999fSMiguel Ojeda let label: Option<Label> = input.parse()?; 2645808c999fSMiguel Ojeda let while_token: Token![while] = input.parse()?; 2646808c999fSMiguel Ojeda let cond = Expr::parse_without_eager_brace(input)?; 2647808c999fSMiguel Ojeda 2648808c999fSMiguel Ojeda let content; 2649808c999fSMiguel Ojeda let brace_token = braced!(content in input); 2650808c999fSMiguel Ojeda attr::parsing::parse_inner(&content, &mut attrs)?; 2651808c999fSMiguel Ojeda let stmts = content.call(Block::parse_within)?; 2652808c999fSMiguel Ojeda 2653808c999fSMiguel Ojeda Ok(ExprWhile { 2654808c999fSMiguel Ojeda attrs, 2655808c999fSMiguel Ojeda label, 2656808c999fSMiguel Ojeda while_token, 2657808c999fSMiguel Ojeda cond: Box::new(cond), 2658808c999fSMiguel Ojeda body: Block { brace_token, stmts }, 2659808c999fSMiguel Ojeda }) 2660808c999fSMiguel Ojeda } 2661808c999fSMiguel Ojeda } 2662808c999fSMiguel Ojeda 2663808c999fSMiguel Ojeda #[cfg(feature = "full")] 2664808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2665808c999fSMiguel Ojeda impl Parse for ExprConst { parse(input: ParseStream) -> Result<Self>2666808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2667808c999fSMiguel Ojeda let const_token: Token![const] = input.parse()?; 2668808c999fSMiguel Ojeda 2669808c999fSMiguel Ojeda let content; 2670808c999fSMiguel Ojeda let brace_token = braced!(content in input); 2671808c999fSMiguel Ojeda let inner_attrs = content.call(Attribute::parse_inner)?; 2672808c999fSMiguel Ojeda let stmts = content.call(Block::parse_within)?; 2673808c999fSMiguel Ojeda 2674808c999fSMiguel Ojeda Ok(ExprConst { 2675808c999fSMiguel Ojeda attrs: inner_attrs, 2676808c999fSMiguel Ojeda const_token, 2677808c999fSMiguel Ojeda block: Block { brace_token, stmts }, 2678808c999fSMiguel Ojeda }) 2679808c999fSMiguel Ojeda } 2680808c999fSMiguel Ojeda } 2681808c999fSMiguel Ojeda 2682808c999fSMiguel Ojeda #[cfg(feature = "full")] 2683808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2684808c999fSMiguel Ojeda impl Parse for Label { parse(input: ParseStream) -> Result<Self>2685808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2686808c999fSMiguel Ojeda Ok(Label { 2687808c999fSMiguel Ojeda name: input.parse()?, 2688808c999fSMiguel Ojeda colon_token: input.parse()?, 2689808c999fSMiguel Ojeda }) 2690808c999fSMiguel Ojeda } 2691808c999fSMiguel Ojeda } 2692808c999fSMiguel Ojeda 2693808c999fSMiguel Ojeda #[cfg(feature = "full")] 2694808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2695808c999fSMiguel Ojeda impl Parse for Option<Label> { parse(input: ParseStream) -> Result<Self>2696808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2697808c999fSMiguel Ojeda if input.peek(Lifetime) { 2698808c999fSMiguel Ojeda input.parse().map(Some) 2699808c999fSMiguel Ojeda } else { 2700808c999fSMiguel Ojeda Ok(None) 2701808c999fSMiguel Ojeda } 2702808c999fSMiguel Ojeda } 2703808c999fSMiguel Ojeda } 2704808c999fSMiguel Ojeda 2705808c999fSMiguel Ojeda #[cfg(feature = "full")] 2706808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2707808c999fSMiguel Ojeda impl Parse for ExprContinue { parse(input: ParseStream) -> Result<Self>2708808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2709808c999fSMiguel Ojeda Ok(ExprContinue { 2710808c999fSMiguel Ojeda attrs: Vec::new(), 2711808c999fSMiguel Ojeda continue_token: input.parse()?, 2712808c999fSMiguel Ojeda label: input.parse()?, 2713808c999fSMiguel Ojeda }) 2714808c999fSMiguel Ojeda } 2715808c999fSMiguel Ojeda } 2716808c999fSMiguel Ojeda 2717808c999fSMiguel Ojeda #[cfg(feature = "full")] expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak>2718808c999fSMiguel Ojeda fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> { 2719808c999fSMiguel Ojeda let break_token: Token![break] = input.parse()?; 2720808c999fSMiguel Ojeda 2721808c999fSMiguel Ojeda let ahead = input.fork(); 2722808c999fSMiguel Ojeda let label: Option<Lifetime> = ahead.parse()?; 2723808c999fSMiguel Ojeda if label.is_some() && ahead.peek(Token![:]) { 2724808c999fSMiguel Ojeda // Not allowed: `break 'label: loop {...}` 2725808c999fSMiguel Ojeda // Parentheses are required. `break ('label: loop {...})` 2726808c999fSMiguel Ojeda let _: Expr = input.parse()?; 2727808c999fSMiguel Ojeda let start_span = label.unwrap().apostrophe; 2728808c999fSMiguel Ojeda let end_span = input.cursor().prev_span(); 2729808c999fSMiguel Ojeda return Err(crate::error::new2( 2730808c999fSMiguel Ojeda start_span, 2731808c999fSMiguel Ojeda end_span, 2732808c999fSMiguel Ojeda "parentheses required", 2733808c999fSMiguel Ojeda )); 2734808c999fSMiguel Ojeda } 2735808c999fSMiguel Ojeda 2736808c999fSMiguel Ojeda input.advance_to(&ahead); 2737808c999fSMiguel Ojeda let expr = if Expr::peek(input) && (allow_struct.0 || !input.peek(token::Brace)) { 2738808c999fSMiguel Ojeda Some(input.parse()?) 2739808c999fSMiguel Ojeda } else { 2740808c999fSMiguel Ojeda None 2741808c999fSMiguel Ojeda }; 2742808c999fSMiguel Ojeda 2743808c999fSMiguel Ojeda Ok(ExprBreak { 2744808c999fSMiguel Ojeda attrs: Vec::new(), 2745808c999fSMiguel Ojeda break_token, 2746808c999fSMiguel Ojeda label, 2747808c999fSMiguel Ojeda expr, 2748808c999fSMiguel Ojeda }) 2749808c999fSMiguel Ojeda } 2750808c999fSMiguel Ojeda 2751808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2752808c999fSMiguel Ojeda impl Parse for FieldValue { parse(input: ParseStream) -> Result<Self>2753808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2754808c999fSMiguel Ojeda let attrs = input.call(Attribute::parse_outer)?; 2755808c999fSMiguel Ojeda let member: Member = input.parse()?; 2756808c999fSMiguel Ojeda let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() { 2757808c999fSMiguel Ojeda let colon_token: Token![:] = input.parse()?; 2758808c999fSMiguel Ojeda let value: Expr = input.parse()?; 2759808c999fSMiguel Ojeda (Some(colon_token), value) 2760808c999fSMiguel Ojeda } else if let Member::Named(ident) = &member { 2761808c999fSMiguel Ojeda let value = Expr::Path(ExprPath { 2762808c999fSMiguel Ojeda attrs: Vec::new(), 2763808c999fSMiguel Ojeda qself: None, 2764808c999fSMiguel Ojeda path: Path::from(ident.clone()), 2765808c999fSMiguel Ojeda }); 2766808c999fSMiguel Ojeda (None, value) 2767808c999fSMiguel Ojeda } else { 2768808c999fSMiguel Ojeda unreachable!() 2769808c999fSMiguel Ojeda }; 2770808c999fSMiguel Ojeda 2771808c999fSMiguel Ojeda Ok(FieldValue { 2772808c999fSMiguel Ojeda attrs, 2773808c999fSMiguel Ojeda member, 2774808c999fSMiguel Ojeda colon_token, 2775808c999fSMiguel Ojeda expr: value, 2776808c999fSMiguel Ojeda }) 2777808c999fSMiguel Ojeda } 2778808c999fSMiguel Ojeda } 2779808c999fSMiguel Ojeda 2780808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2781808c999fSMiguel Ojeda impl Parse for ExprStruct { parse(input: ParseStream) -> Result<Self>2782808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2783808c999fSMiguel Ojeda let expr_style = true; 2784808c999fSMiguel Ojeda let (qself, path) = path::parsing::qpath(input, expr_style)?; 2785808c999fSMiguel Ojeda expr_struct_helper(input, qself, path) 2786808c999fSMiguel Ojeda } 2787808c999fSMiguel Ojeda } 2788808c999fSMiguel Ojeda expr_struct_helper( input: ParseStream, qself: Option<QSelf>, path: Path, ) -> Result<ExprStruct>2789808c999fSMiguel Ojeda fn expr_struct_helper( 2790808c999fSMiguel Ojeda input: ParseStream, 2791808c999fSMiguel Ojeda qself: Option<QSelf>, 2792808c999fSMiguel Ojeda path: Path, 2793808c999fSMiguel Ojeda ) -> Result<ExprStruct> { 2794808c999fSMiguel Ojeda let content; 2795808c999fSMiguel Ojeda let brace_token = braced!(content in input); 2796808c999fSMiguel Ojeda 2797808c999fSMiguel Ojeda let mut fields = Punctuated::new(); 2798808c999fSMiguel Ojeda while !content.is_empty() { 2799808c999fSMiguel Ojeda if content.peek(Token![..]) { 2800808c999fSMiguel Ojeda return Ok(ExprStruct { 2801808c999fSMiguel Ojeda attrs: Vec::new(), 2802808c999fSMiguel Ojeda qself, 2803808c999fSMiguel Ojeda path, 2804808c999fSMiguel Ojeda brace_token, 2805808c999fSMiguel Ojeda fields, 2806808c999fSMiguel Ojeda dot2_token: Some(content.parse()?), 2807808c999fSMiguel Ojeda rest: if content.is_empty() { 2808808c999fSMiguel Ojeda None 2809808c999fSMiguel Ojeda } else { 2810808c999fSMiguel Ojeda Some(Box::new(content.parse()?)) 2811808c999fSMiguel Ojeda }, 2812808c999fSMiguel Ojeda }); 2813808c999fSMiguel Ojeda } 2814808c999fSMiguel Ojeda 2815808c999fSMiguel Ojeda fields.push(content.parse()?); 2816808c999fSMiguel Ojeda if content.is_empty() { 2817808c999fSMiguel Ojeda break; 2818808c999fSMiguel Ojeda } 2819808c999fSMiguel Ojeda let punct: Token![,] = content.parse()?; 2820808c999fSMiguel Ojeda fields.push_punct(punct); 2821808c999fSMiguel Ojeda } 2822808c999fSMiguel Ojeda 2823808c999fSMiguel Ojeda Ok(ExprStruct { 2824808c999fSMiguel Ojeda attrs: Vec::new(), 2825808c999fSMiguel Ojeda qself, 2826808c999fSMiguel Ojeda path, 2827808c999fSMiguel Ojeda brace_token, 2828808c999fSMiguel Ojeda fields, 2829808c999fSMiguel Ojeda dot2_token: None, 2830808c999fSMiguel Ojeda rest: None, 2831808c999fSMiguel Ojeda }) 2832808c999fSMiguel Ojeda } 2833808c999fSMiguel Ojeda 2834808c999fSMiguel Ojeda #[cfg(feature = "full")] 2835808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2836808c999fSMiguel Ojeda impl Parse for ExprUnsafe { parse(input: ParseStream) -> Result<Self>2837808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2838808c999fSMiguel Ojeda let unsafe_token: Token![unsafe] = input.parse()?; 2839808c999fSMiguel Ojeda 2840808c999fSMiguel Ojeda let content; 2841808c999fSMiguel Ojeda let brace_token = braced!(content in input); 2842808c999fSMiguel Ojeda let inner_attrs = content.call(Attribute::parse_inner)?; 2843808c999fSMiguel Ojeda let stmts = content.call(Block::parse_within)?; 2844808c999fSMiguel Ojeda 2845808c999fSMiguel Ojeda Ok(ExprUnsafe { 2846808c999fSMiguel Ojeda attrs: inner_attrs, 2847808c999fSMiguel Ojeda unsafe_token, 2848808c999fSMiguel Ojeda block: Block { brace_token, stmts }, 2849808c999fSMiguel Ojeda }) 2850808c999fSMiguel Ojeda } 2851808c999fSMiguel Ojeda } 2852808c999fSMiguel Ojeda 2853808c999fSMiguel Ojeda #[cfg(feature = "full")] 2854808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2855808c999fSMiguel Ojeda impl Parse for ExprBlock { parse(input: ParseStream) -> Result<Self>2856808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2857808c999fSMiguel Ojeda let mut attrs = input.call(Attribute::parse_outer)?; 2858808c999fSMiguel Ojeda let label: Option<Label> = input.parse()?; 2859808c999fSMiguel Ojeda 2860808c999fSMiguel Ojeda let content; 2861808c999fSMiguel Ojeda let brace_token = braced!(content in input); 2862808c999fSMiguel Ojeda attr::parsing::parse_inner(&content, &mut attrs)?; 2863808c999fSMiguel Ojeda let stmts = content.call(Block::parse_within)?; 2864808c999fSMiguel Ojeda 2865808c999fSMiguel Ojeda Ok(ExprBlock { 2866808c999fSMiguel Ojeda attrs, 2867808c999fSMiguel Ojeda label, 2868808c999fSMiguel Ojeda block: Block { brace_token, stmts }, 2869808c999fSMiguel Ojeda }) 2870808c999fSMiguel Ojeda } 2871808c999fSMiguel Ojeda } 2872808c999fSMiguel Ojeda 2873808c999fSMiguel Ojeda #[cfg(feature = "full")] expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange>2874808c999fSMiguel Ojeda fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> { 2875808c999fSMiguel Ojeda let limits: RangeLimits = input.parse()?; 2876808c999fSMiguel Ojeda let end = parse_range_end(input, &limits, allow_struct)?; 2877808c999fSMiguel Ojeda Ok(ExprRange { 2878808c999fSMiguel Ojeda attrs: Vec::new(), 2879808c999fSMiguel Ojeda start: None, 2880808c999fSMiguel Ojeda limits, 2881808c999fSMiguel Ojeda end, 2882808c999fSMiguel Ojeda }) 2883808c999fSMiguel Ojeda } 2884808c999fSMiguel Ojeda 2885808c999fSMiguel Ojeda #[cfg(feature = "full")] parse_range_end( input: ParseStream, limits: &RangeLimits, allow_struct: AllowStruct, ) -> Result<Option<Box<Expr>>>2886808c999fSMiguel Ojeda fn parse_range_end( 2887808c999fSMiguel Ojeda input: ParseStream, 2888808c999fSMiguel Ojeda limits: &RangeLimits, 2889808c999fSMiguel Ojeda allow_struct: AllowStruct, 2890808c999fSMiguel Ojeda ) -> Result<Option<Box<Expr>>> { 2891808c999fSMiguel Ojeda if matches!(limits, RangeLimits::HalfOpen(_)) 2892808c999fSMiguel Ojeda && (input.is_empty() 2893808c999fSMiguel Ojeda || input.peek(Token![,]) 2894808c999fSMiguel Ojeda || input.peek(Token![;]) 2895808c999fSMiguel Ojeda || input.peek(Token![.]) && !input.peek(Token![..]) 2896808c999fSMiguel Ojeda || input.peek(Token![?]) 2897808c999fSMiguel Ojeda || input.peek(Token![=>]) 2898808c999fSMiguel Ojeda || !allow_struct.0 && input.peek(token::Brace) 2899808c999fSMiguel Ojeda || input.peek(Token![=]) 2900808c999fSMiguel Ojeda || input.peek(Token![+]) 2901808c999fSMiguel Ojeda || input.peek(Token![/]) 2902808c999fSMiguel Ojeda || input.peek(Token![%]) 2903808c999fSMiguel Ojeda || input.peek(Token![^]) 2904808c999fSMiguel Ojeda || input.peek(Token![>]) 2905808c999fSMiguel Ojeda || input.peek(Token![<=]) 2906808c999fSMiguel Ojeda || input.peek(Token![!=]) 2907808c999fSMiguel Ojeda || input.peek(Token![-=]) 2908808c999fSMiguel Ojeda || input.peek(Token![*=]) 2909808c999fSMiguel Ojeda || input.peek(Token![&=]) 2910808c999fSMiguel Ojeda || input.peek(Token![|=]) 2911808c999fSMiguel Ojeda || input.peek(Token![<<=]) 2912808c999fSMiguel Ojeda || input.peek(Token![as])) 2913808c999fSMiguel Ojeda { 2914808c999fSMiguel Ojeda Ok(None) 2915808c999fSMiguel Ojeda } else { 2916808c999fSMiguel Ojeda let end = parse_binop_rhs(input, allow_struct, Precedence::Range)?; 2917808c999fSMiguel Ojeda Ok(Some(end)) 2918808c999fSMiguel Ojeda } 2919808c999fSMiguel Ojeda } 2920808c999fSMiguel Ojeda 2921808c999fSMiguel Ojeda #[cfg(feature = "full")] 2922808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2923808c999fSMiguel Ojeda impl Parse for RangeLimits { parse(input: ParseStream) -> Result<Self>2924808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2925808c999fSMiguel Ojeda let lookahead = input.lookahead1(); 2926808c999fSMiguel Ojeda let dot_dot = lookahead.peek(Token![..]); 2927808c999fSMiguel Ojeda let dot_dot_eq = dot_dot && lookahead.peek(Token![..=]); 2928808c999fSMiguel Ojeda let dot_dot_dot = dot_dot && input.peek(Token![...]); 2929808c999fSMiguel Ojeda if dot_dot_eq { 2930808c999fSMiguel Ojeda input.parse().map(RangeLimits::Closed) 2931808c999fSMiguel Ojeda } else if dot_dot && !dot_dot_dot { 2932808c999fSMiguel Ojeda input.parse().map(RangeLimits::HalfOpen) 2933808c999fSMiguel Ojeda } else { 2934808c999fSMiguel Ojeda Err(lookahead.error()) 2935808c999fSMiguel Ojeda } 2936808c999fSMiguel Ojeda } 2937808c999fSMiguel Ojeda } 2938808c999fSMiguel Ojeda 2939808c999fSMiguel Ojeda #[cfg(feature = "full")] 2940808c999fSMiguel Ojeda impl RangeLimits { parse_obsolete(input: ParseStream) -> Result<Self>2941808c999fSMiguel Ojeda pub(crate) fn parse_obsolete(input: ParseStream) -> Result<Self> { 2942808c999fSMiguel Ojeda let lookahead = input.lookahead1(); 2943808c999fSMiguel Ojeda let dot_dot = lookahead.peek(Token![..]); 2944808c999fSMiguel Ojeda let dot_dot_eq = dot_dot && lookahead.peek(Token![..=]); 2945808c999fSMiguel Ojeda let dot_dot_dot = dot_dot && input.peek(Token![...]); 2946808c999fSMiguel Ojeda if dot_dot_eq { 2947808c999fSMiguel Ojeda input.parse().map(RangeLimits::Closed) 2948808c999fSMiguel Ojeda } else if dot_dot_dot { 2949808c999fSMiguel Ojeda let dot3: Token![...] = input.parse()?; 2950808c999fSMiguel Ojeda Ok(RangeLimits::Closed(Token)) 2951808c999fSMiguel Ojeda } else if dot_dot { 2952808c999fSMiguel Ojeda input.parse().map(RangeLimits::HalfOpen) 2953808c999fSMiguel Ojeda } else { 2954808c999fSMiguel Ojeda Err(lookahead.error()) 2955808c999fSMiguel Ojeda } 2956808c999fSMiguel Ojeda } 2957808c999fSMiguel Ojeda } 2958808c999fSMiguel Ojeda 2959808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2960808c999fSMiguel Ojeda impl Parse for ExprPath { parse(input: ParseStream) -> Result<Self>2961808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2962808c999fSMiguel Ojeda #[cfg(not(feature = "full"))] 2963808c999fSMiguel Ojeda let attrs = Vec::new(); 2964808c999fSMiguel Ojeda #[cfg(feature = "full")] 2965808c999fSMiguel Ojeda let attrs = input.call(Attribute::parse_outer)?; 2966808c999fSMiguel Ojeda 2967808c999fSMiguel Ojeda let expr_style = true; 2968808c999fSMiguel Ojeda let (qself, path) = path::parsing::qpath(input, expr_style)?; 2969808c999fSMiguel Ojeda 2970808c999fSMiguel Ojeda Ok(ExprPath { attrs, qself, path }) 2971808c999fSMiguel Ojeda } 2972808c999fSMiguel Ojeda } 2973808c999fSMiguel Ojeda 2974808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 2975808c999fSMiguel Ojeda impl Parse for Member { parse(input: ParseStream) -> Result<Self>2976808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 2977808c999fSMiguel Ojeda if input.peek(Ident) { 2978808c999fSMiguel Ojeda input.parse().map(Member::Named) 2979808c999fSMiguel Ojeda } else if input.peek(LitInt) { 2980808c999fSMiguel Ojeda input.parse().map(Member::Unnamed) 2981808c999fSMiguel Ojeda } else { 2982808c999fSMiguel Ojeda Err(input.error("expected identifier or integer")) 2983808c999fSMiguel Ojeda } 2984808c999fSMiguel Ojeda } 2985808c999fSMiguel Ojeda } 2986808c999fSMiguel Ojeda 2987808c999fSMiguel Ojeda #[cfg(feature = "full")] 2988808c999fSMiguel Ojeda impl Arm { parse_multiple(input: ParseStream) -> Result<Vec<Self>>2989808c999fSMiguel Ojeda pub(crate) fn parse_multiple(input: ParseStream) -> Result<Vec<Self>> { 2990808c999fSMiguel Ojeda let mut arms = Vec::new(); 2991808c999fSMiguel Ojeda while !input.is_empty() { 2992808c999fSMiguel Ojeda arms.push(input.call(Arm::parse)?); 2993808c999fSMiguel Ojeda } 2994808c999fSMiguel Ojeda Ok(arms) 2995808c999fSMiguel Ojeda } 2996808c999fSMiguel Ojeda } 2997808c999fSMiguel Ojeda 2998808c999fSMiguel Ojeda #[cfg(feature = "full")] 2999808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 3000808c999fSMiguel Ojeda impl Parse for Arm { parse(input: ParseStream) -> Result<Arm>3001808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Arm> { 3002808c999fSMiguel Ojeda let requires_comma; 3003808c999fSMiguel Ojeda Ok(Arm { 3004808c999fSMiguel Ojeda attrs: input.call(Attribute::parse_outer)?, 3005808c999fSMiguel Ojeda pat: Pat::parse_multi_with_leading_vert(input)?, 3006808c999fSMiguel Ojeda guard: { 3007808c999fSMiguel Ojeda if input.peek(Token![if]) { 3008808c999fSMiguel Ojeda let if_token: Token![if] = input.parse()?; 3009808c999fSMiguel Ojeda let guard: Expr = input.parse()?; 3010808c999fSMiguel Ojeda Some((if_token, Box::new(guard))) 3011808c999fSMiguel Ojeda } else { 3012808c999fSMiguel Ojeda None 3013808c999fSMiguel Ojeda } 3014808c999fSMiguel Ojeda }, 3015808c999fSMiguel Ojeda fat_arrow_token: input.parse()?, 3016808c999fSMiguel Ojeda body: { 3017808c999fSMiguel Ojeda let body = Expr::parse_with_earlier_boundary_rule(input)?; 3018808c999fSMiguel Ojeda requires_comma = classify::requires_comma_to_be_match_arm(&body); 3019808c999fSMiguel Ojeda Box::new(body) 3020808c999fSMiguel Ojeda }, 3021808c999fSMiguel Ojeda comma: { 3022808c999fSMiguel Ojeda if requires_comma && !input.is_empty() { 3023808c999fSMiguel Ojeda Some(input.parse()?) 3024808c999fSMiguel Ojeda } else { 3025808c999fSMiguel Ojeda input.parse()? 3026808c999fSMiguel Ojeda } 3027808c999fSMiguel Ojeda }, 3028808c999fSMiguel Ojeda }) 3029808c999fSMiguel Ojeda } 3030808c999fSMiguel Ojeda } 3031808c999fSMiguel Ojeda 3032808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 3033808c999fSMiguel Ojeda impl Parse for Index { parse(input: ParseStream) -> Result<Self>3034808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 3035808c999fSMiguel Ojeda let lit: LitInt = input.parse()?; 3036808c999fSMiguel Ojeda if lit.suffix().is_empty() { 3037808c999fSMiguel Ojeda Ok(Index { 3038808c999fSMiguel Ojeda index: lit 3039808c999fSMiguel Ojeda .base10_digits() 3040808c999fSMiguel Ojeda .parse() 3041808c999fSMiguel Ojeda .map_err(|err| Error::new(lit.span(), err))?, 3042808c999fSMiguel Ojeda span: lit.span(), 3043808c999fSMiguel Ojeda }) 3044808c999fSMiguel Ojeda } else { 3045808c999fSMiguel Ojeda Err(Error::new(lit.span(), "expected unsuffixed integer")) 3046808c999fSMiguel Ojeda } 3047808c999fSMiguel Ojeda } 3048808c999fSMiguel Ojeda } 3049808c999fSMiguel Ojeda multi_index(e: &mut Expr, dot_token: &mut Token![.], float: LitFloat) -> Result<bool>3050808c999fSMiguel Ojeda fn multi_index(e: &mut Expr, dot_token: &mut Token![.], float: LitFloat) -> Result<bool> { 3051808c999fSMiguel Ojeda let float_token = float.token(); 3052808c999fSMiguel Ojeda let float_span = float_token.span(); 3053808c999fSMiguel Ojeda let mut float_repr = float_token.to_string(); 3054808c999fSMiguel Ojeda let trailing_dot = float_repr.ends_with('.'); 3055808c999fSMiguel Ojeda if trailing_dot { 3056808c999fSMiguel Ojeda float_repr.truncate(float_repr.len() - 1); 3057808c999fSMiguel Ojeda } 3058808c999fSMiguel Ojeda 3059808c999fSMiguel Ojeda let mut offset = 0; 3060808c999fSMiguel Ojeda for part in float_repr.split('.') { 3061808c999fSMiguel Ojeda let mut index: Index = 3062808c999fSMiguel Ojeda crate::parse_str(part).map_err(|err| Error::new(float_span, err))?; 3063808c999fSMiguel Ojeda let part_end = offset + part.len(); 3064808c999fSMiguel Ojeda index.span = float_token.subspan(offset..part_end).unwrap_or(float_span); 3065808c999fSMiguel Ojeda 3066808c999fSMiguel Ojeda let base = mem::replace(e, Expr::PLACEHOLDER); 3067808c999fSMiguel Ojeda *e = Expr::Field(ExprField { 3068808c999fSMiguel Ojeda attrs: Vec::new(), 3069808c999fSMiguel Ojeda base: Box::new(base), 3070808c999fSMiguel Ojeda dot_token: Token, 3071808c999fSMiguel Ojeda member: Member::Unnamed(index), 3072808c999fSMiguel Ojeda }); 3073808c999fSMiguel Ojeda 3074808c999fSMiguel Ojeda let dot_span = float_token 3075808c999fSMiguel Ojeda .subspan(part_end..part_end + 1) 3076808c999fSMiguel Ojeda .unwrap_or(float_span); 3077808c999fSMiguel Ojeda *dot_token = Token; 3078808c999fSMiguel Ojeda offset = part_end + 1; 3079808c999fSMiguel Ojeda } 3080808c999fSMiguel Ojeda 3081808c999fSMiguel Ojeda Ok(!trailing_dot) 3082808c999fSMiguel Ojeda } 3083808c999fSMiguel Ojeda 3084808c999fSMiguel Ojeda #[cfg(feature = "full")] 3085808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 3086808c999fSMiguel Ojeda impl Parse for PointerMutability { parse(input: ParseStream) -> Result<Self>3087808c999fSMiguel Ojeda fn parse(input: ParseStream) -> Result<Self> { 3088808c999fSMiguel Ojeda let lookahead = input.lookahead1(); 3089808c999fSMiguel Ojeda if lookahead.peek(Token![const]) { 3090808c999fSMiguel Ojeda Ok(PointerMutability::Const(input.parse()?)) 3091808c999fSMiguel Ojeda } else if lookahead.peek(Token![mut]) { 3092808c999fSMiguel Ojeda Ok(PointerMutability::Mut(input.parse()?)) 3093808c999fSMiguel Ojeda } else { 3094808c999fSMiguel Ojeda Err(lookahead.error()) 3095808c999fSMiguel Ojeda } 3096808c999fSMiguel Ojeda } 3097808c999fSMiguel Ojeda } 3098808c999fSMiguel Ojeda check_cast(input: ParseStream) -> Result<()>3099808c999fSMiguel Ojeda fn check_cast(input: ParseStream) -> Result<()> { 3100808c999fSMiguel Ojeda let kind = if input.peek(Token![.]) && !input.peek(Token![..]) { 3101808c999fSMiguel Ojeda if input.peek2(Token![await]) { 3102808c999fSMiguel Ojeda "`.await`" 3103808c999fSMiguel Ojeda } else if input.peek2(Ident) && (input.peek3(token::Paren) || input.peek3(Token![::])) { 3104808c999fSMiguel Ojeda "a method call" 3105808c999fSMiguel Ojeda } else { 3106808c999fSMiguel Ojeda "a field access" 3107808c999fSMiguel Ojeda } 3108808c999fSMiguel Ojeda } else if input.peek(Token![?]) { 3109808c999fSMiguel Ojeda "`?`" 3110808c999fSMiguel Ojeda } else if input.peek(token::Bracket) { 3111808c999fSMiguel Ojeda "indexing" 3112808c999fSMiguel Ojeda } else if input.peek(token::Paren) { 3113808c999fSMiguel Ojeda "a function call" 3114808c999fSMiguel Ojeda } else { 3115808c999fSMiguel Ojeda return Ok(()); 3116808c999fSMiguel Ojeda }; 3117808c999fSMiguel Ojeda let msg = format!("casts cannot be followed by {}", kind); 3118808c999fSMiguel Ojeda Err(input.error(msg)) 3119808c999fSMiguel Ojeda } 3120808c999fSMiguel Ojeda } 3121808c999fSMiguel Ojeda 3122808c999fSMiguel Ojeda #[cfg(feature = "printing")] 3123808c999fSMiguel Ojeda pub(crate) mod printing { 3124808c999fSMiguel Ojeda use crate::attr::Attribute; 3125808c999fSMiguel Ojeda #[cfg(feature = "full")] 3126808c999fSMiguel Ojeda use crate::attr::FilterAttrs; 3127808c999fSMiguel Ojeda #[cfg(feature = "full")] 3128808c999fSMiguel Ojeda use crate::classify; 3129808c999fSMiguel Ojeda #[cfg(feature = "full")] 3130808c999fSMiguel Ojeda use crate::expr::{ 3131808c999fSMiguel Ojeda Arm, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure, 3132808c999fSMiguel Ojeda ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch, 3133808c999fSMiguel Ojeda ExprRange, ExprRawAddr, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprUnsafe, 3134808c999fSMiguel Ojeda ExprWhile, ExprYield, Label, PointerMutability, RangeLimits, 3135808c999fSMiguel Ojeda }; 3136808c999fSMiguel Ojeda use crate::expr::{ 3137808c999fSMiguel Ojeda Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprGroup, ExprIndex, ExprLit, ExprMacro, 3138808c999fSMiguel Ojeda ExprMethodCall, ExprParen, ExprPath, ExprReference, ExprStruct, ExprTuple, ExprUnary, 3139808c999fSMiguel Ojeda FieldValue, Index, Member, 3140808c999fSMiguel Ojeda }; 3141808c999fSMiguel Ojeda use crate::fixup::FixupContext; 3142808c999fSMiguel Ojeda use crate::op::BinOp; 3143808c999fSMiguel Ojeda use crate::path; 3144808c999fSMiguel Ojeda use crate::path::printing::PathStyle; 3145808c999fSMiguel Ojeda use crate::precedence::Precedence; 3146808c999fSMiguel Ojeda use crate::token; 3147808c999fSMiguel Ojeda #[cfg(feature = "full")] 3148808c999fSMiguel Ojeda use crate::ty::ReturnType; 3149808c999fSMiguel Ojeda use proc_macro2::{Literal, Span, TokenStream}; 3150808c999fSMiguel Ojeda use quote::{ToTokens, TokenStreamExt}; 3151808c999fSMiguel Ojeda 3152808c999fSMiguel Ojeda #[cfg(feature = "full")] outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream)3153808c999fSMiguel Ojeda pub(crate) fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) { 3154808c999fSMiguel Ojeda tokens.append_all(attrs.outer()); 3155808c999fSMiguel Ojeda } 3156808c999fSMiguel Ojeda 3157808c999fSMiguel Ojeda #[cfg(feature = "full")] inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream)3158808c999fSMiguel Ojeda fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) { 3159808c999fSMiguel Ojeda tokens.append_all(attrs.inner()); 3160808c999fSMiguel Ojeda } 3161808c999fSMiguel Ojeda 3162808c999fSMiguel Ojeda #[cfg(not(feature = "full"))] outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream)3163808c999fSMiguel Ojeda pub(crate) fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {} 3164808c999fSMiguel Ojeda print_subexpression( expr: &Expr, needs_group: bool, tokens: &mut TokenStream, mut fixup: FixupContext, )3165808c999fSMiguel Ojeda pub(crate) fn print_subexpression( 3166808c999fSMiguel Ojeda expr: &Expr, 3167808c999fSMiguel Ojeda needs_group: bool, 3168808c999fSMiguel Ojeda tokens: &mut TokenStream, 3169808c999fSMiguel Ojeda mut fixup: FixupContext, 3170808c999fSMiguel Ojeda ) { 3171808c999fSMiguel Ojeda if needs_group { 3172808c999fSMiguel Ojeda // If we are surrounding the whole cond in parentheses, such as: 3173808c999fSMiguel Ojeda // 3174808c999fSMiguel Ojeda // if (return Struct {}) {} 3175808c999fSMiguel Ojeda // 3176808c999fSMiguel Ojeda // then there is no need for parenthesizing the individual struct 3177808c999fSMiguel Ojeda // expressions within. On the other hand if the whole cond is not 3178808c999fSMiguel Ojeda // parenthesized, then print_expr must parenthesize exterior struct 3179808c999fSMiguel Ojeda // literals. 3180808c999fSMiguel Ojeda // 3181808c999fSMiguel Ojeda // if x == (Struct {}) {} 3182808c999fSMiguel Ojeda // 3183808c999fSMiguel Ojeda fixup = FixupContext::NONE; 3184808c999fSMiguel Ojeda } 3185808c999fSMiguel Ojeda 3186808c999fSMiguel Ojeda let do_print_expr = |tokens: &mut TokenStream| print_expr(expr, tokens, fixup); 3187808c999fSMiguel Ojeda 3188808c999fSMiguel Ojeda if needs_group { 3189808c999fSMiguel Ojeda token::Paren::default().surround(tokens, do_print_expr); 3190808c999fSMiguel Ojeda } else { 3191808c999fSMiguel Ojeda do_print_expr(tokens); 3192808c999fSMiguel Ojeda } 3193808c999fSMiguel Ojeda } 3194808c999fSMiguel Ojeda print_expr(expr: &Expr, tokens: &mut TokenStream, mut fixup: FixupContext)3195808c999fSMiguel Ojeda pub(crate) fn print_expr(expr: &Expr, tokens: &mut TokenStream, mut fixup: FixupContext) { 3196808c999fSMiguel Ojeda #[cfg(feature = "full")] 3197808c999fSMiguel Ojeda let needs_group = fixup.parenthesize(expr); 3198808c999fSMiguel Ojeda #[cfg(not(feature = "full"))] 3199808c999fSMiguel Ojeda let needs_group = false; 3200808c999fSMiguel Ojeda 3201808c999fSMiguel Ojeda if needs_group { 3202808c999fSMiguel Ojeda fixup = FixupContext::NONE; 3203808c999fSMiguel Ojeda } 3204808c999fSMiguel Ojeda 3205808c999fSMiguel Ojeda let do_print_expr = |tokens: &mut TokenStream| match expr { 3206808c999fSMiguel Ojeda #[cfg(feature = "full")] 3207808c999fSMiguel Ojeda Expr::Array(e) => e.to_tokens(tokens), 3208808c999fSMiguel Ojeda #[cfg(feature = "full")] 3209808c999fSMiguel Ojeda Expr::Assign(e) => print_expr_assign(e, tokens, fixup), 3210808c999fSMiguel Ojeda #[cfg(feature = "full")] 3211808c999fSMiguel Ojeda Expr::Async(e) => e.to_tokens(tokens), 3212808c999fSMiguel Ojeda #[cfg(feature = "full")] 3213808c999fSMiguel Ojeda Expr::Await(e) => print_expr_await(e, tokens, fixup), 3214808c999fSMiguel Ojeda Expr::Binary(e) => print_expr_binary(e, tokens, fixup), 3215808c999fSMiguel Ojeda #[cfg(feature = "full")] 3216808c999fSMiguel Ojeda Expr::Block(e) => e.to_tokens(tokens), 3217808c999fSMiguel Ojeda #[cfg(feature = "full")] 3218808c999fSMiguel Ojeda Expr::Break(e) => print_expr_break(e, tokens, fixup), 3219808c999fSMiguel Ojeda Expr::Call(e) => print_expr_call(e, tokens, fixup), 3220808c999fSMiguel Ojeda Expr::Cast(e) => print_expr_cast(e, tokens, fixup), 3221808c999fSMiguel Ojeda #[cfg(feature = "full")] 3222808c999fSMiguel Ojeda Expr::Closure(e) => print_expr_closure(e, tokens, fixup), 3223808c999fSMiguel Ojeda #[cfg(feature = "full")] 3224808c999fSMiguel Ojeda Expr::Const(e) => e.to_tokens(tokens), 3225808c999fSMiguel Ojeda #[cfg(feature = "full")] 3226808c999fSMiguel Ojeda Expr::Continue(e) => e.to_tokens(tokens), 3227808c999fSMiguel Ojeda Expr::Field(e) => print_expr_field(e, tokens, fixup), 3228808c999fSMiguel Ojeda #[cfg(feature = "full")] 3229808c999fSMiguel Ojeda Expr::ForLoop(e) => e.to_tokens(tokens), 3230808c999fSMiguel Ojeda Expr::Group(e) => e.to_tokens(tokens), 3231808c999fSMiguel Ojeda #[cfg(feature = "full")] 3232808c999fSMiguel Ojeda Expr::If(e) => e.to_tokens(tokens), 3233808c999fSMiguel Ojeda Expr::Index(e) => print_expr_index(e, tokens, fixup), 3234808c999fSMiguel Ojeda #[cfg(feature = "full")] 3235808c999fSMiguel Ojeda Expr::Infer(e) => e.to_tokens(tokens), 3236808c999fSMiguel Ojeda #[cfg(feature = "full")] 3237808c999fSMiguel Ojeda Expr::Let(e) => print_expr_let(e, tokens, fixup), 3238808c999fSMiguel Ojeda Expr::Lit(e) => e.to_tokens(tokens), 3239808c999fSMiguel Ojeda #[cfg(feature = "full")] 3240808c999fSMiguel Ojeda Expr::Loop(e) => e.to_tokens(tokens), 3241808c999fSMiguel Ojeda Expr::Macro(e) => e.to_tokens(tokens), 3242808c999fSMiguel Ojeda #[cfg(feature = "full")] 3243808c999fSMiguel Ojeda Expr::Match(e) => e.to_tokens(tokens), 3244808c999fSMiguel Ojeda Expr::MethodCall(e) => print_expr_method_call(e, tokens, fixup), 3245808c999fSMiguel Ojeda Expr::Paren(e) => e.to_tokens(tokens), 3246808c999fSMiguel Ojeda Expr::Path(e) => e.to_tokens(tokens), 3247808c999fSMiguel Ojeda #[cfg(feature = "full")] 3248808c999fSMiguel Ojeda Expr::Range(e) => print_expr_range(e, tokens, fixup), 3249808c999fSMiguel Ojeda #[cfg(feature = "full")] 3250808c999fSMiguel Ojeda Expr::RawAddr(e) => print_expr_raw_addr(e, tokens, fixup), 3251808c999fSMiguel Ojeda Expr::Reference(e) => print_expr_reference(e, tokens, fixup), 3252808c999fSMiguel Ojeda #[cfg(feature = "full")] 3253808c999fSMiguel Ojeda Expr::Repeat(e) => e.to_tokens(tokens), 3254808c999fSMiguel Ojeda #[cfg(feature = "full")] 3255808c999fSMiguel Ojeda Expr::Return(e) => print_expr_return(e, tokens, fixup), 3256808c999fSMiguel Ojeda Expr::Struct(e) => e.to_tokens(tokens), 3257808c999fSMiguel Ojeda #[cfg(feature = "full")] 3258808c999fSMiguel Ojeda Expr::Try(e) => print_expr_try(e, tokens, fixup), 3259808c999fSMiguel Ojeda #[cfg(feature = "full")] 3260808c999fSMiguel Ojeda Expr::TryBlock(e) => e.to_tokens(tokens), 3261808c999fSMiguel Ojeda Expr::Tuple(e) => e.to_tokens(tokens), 3262808c999fSMiguel Ojeda Expr::Unary(e) => print_expr_unary(e, tokens, fixup), 3263808c999fSMiguel Ojeda #[cfg(feature = "full")] 3264808c999fSMiguel Ojeda Expr::Unsafe(e) => e.to_tokens(tokens), 3265808c999fSMiguel Ojeda Expr::Verbatim(e) => e.to_tokens(tokens), 3266808c999fSMiguel Ojeda #[cfg(feature = "full")] 3267808c999fSMiguel Ojeda Expr::While(e) => e.to_tokens(tokens), 3268808c999fSMiguel Ojeda #[cfg(feature = "full")] 3269808c999fSMiguel Ojeda Expr::Yield(e) => print_expr_yield(e, tokens, fixup), 3270808c999fSMiguel Ojeda 3271808c999fSMiguel Ojeda #[cfg(not(feature = "full"))] 3272808c999fSMiguel Ojeda _ => unreachable!(), 3273808c999fSMiguel Ojeda }; 3274808c999fSMiguel Ojeda 3275808c999fSMiguel Ojeda if needs_group { 3276808c999fSMiguel Ojeda token::Paren::default().surround(tokens, do_print_expr); 3277808c999fSMiguel Ojeda } else { 3278808c999fSMiguel Ojeda do_print_expr(tokens); 3279808c999fSMiguel Ojeda } 3280808c999fSMiguel Ojeda } 3281808c999fSMiguel Ojeda 3282808c999fSMiguel Ojeda #[cfg(feature = "full")] 3283808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3284808c999fSMiguel Ojeda impl ToTokens for ExprArray { to_tokens(&self, tokens: &mut TokenStream)3285808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3286808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3287808c999fSMiguel Ojeda self.bracket_token.surround(tokens, |tokens| { 3288808c999fSMiguel Ojeda self.elems.to_tokens(tokens); 3289808c999fSMiguel Ojeda }); 3290808c999fSMiguel Ojeda } 3291808c999fSMiguel Ojeda } 3292808c999fSMiguel Ojeda 3293808c999fSMiguel Ojeda #[cfg(feature = "full")] 3294808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3295808c999fSMiguel Ojeda impl ToTokens for ExprAssign { to_tokens(&self, tokens: &mut TokenStream)3296808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3297808c999fSMiguel Ojeda print_expr_assign(self, tokens, FixupContext::NONE); 3298808c999fSMiguel Ojeda } 3299808c999fSMiguel Ojeda } 3300808c999fSMiguel Ojeda 3301808c999fSMiguel Ojeda #[cfg(feature = "full")] print_expr_assign(e: &ExprAssign, tokens: &mut TokenStream, mut fixup: FixupContext)3302808c999fSMiguel Ojeda fn print_expr_assign(e: &ExprAssign, tokens: &mut TokenStream, mut fixup: FixupContext) { 3303808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3304808c999fSMiguel Ojeda 3305808c999fSMiguel Ojeda let needs_group = !e.attrs.is_empty(); 3306808c999fSMiguel Ojeda if needs_group { 3307808c999fSMiguel Ojeda fixup = FixupContext::NONE; 3308808c999fSMiguel Ojeda } 3309808c999fSMiguel Ojeda 3310808c999fSMiguel Ojeda let do_print_expr = |tokens: &mut TokenStream| { 3311808c999fSMiguel Ojeda let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator( 3312808c999fSMiguel Ojeda &e.left, 3313808c999fSMiguel Ojeda false, 3314808c999fSMiguel Ojeda false, 3315808c999fSMiguel Ojeda Precedence::Assign, 3316808c999fSMiguel Ojeda ); 3317808c999fSMiguel Ojeda print_subexpression(&e.left, left_prec <= Precedence::Range, tokens, left_fixup); 3318808c999fSMiguel Ojeda e.eq_token.to_tokens(tokens); 3319808c999fSMiguel Ojeda print_expr( 3320808c999fSMiguel Ojeda &e.right, 3321808c999fSMiguel Ojeda tokens, 3322808c999fSMiguel Ojeda fixup.rightmost_subexpression_fixup(false, false, Precedence::Assign), 3323808c999fSMiguel Ojeda ); 3324808c999fSMiguel Ojeda }; 3325808c999fSMiguel Ojeda 3326808c999fSMiguel Ojeda if needs_group { 3327808c999fSMiguel Ojeda token::Paren::default().surround(tokens, do_print_expr); 3328808c999fSMiguel Ojeda } else { 3329808c999fSMiguel Ojeda do_print_expr(tokens); 3330808c999fSMiguel Ojeda } 3331808c999fSMiguel Ojeda } 3332808c999fSMiguel Ojeda 3333808c999fSMiguel Ojeda #[cfg(feature = "full")] 3334808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3335808c999fSMiguel Ojeda impl ToTokens for ExprAsync { to_tokens(&self, tokens: &mut TokenStream)3336808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3337808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3338808c999fSMiguel Ojeda self.async_token.to_tokens(tokens); 3339808c999fSMiguel Ojeda self.capture.to_tokens(tokens); 3340808c999fSMiguel Ojeda self.block.to_tokens(tokens); 3341808c999fSMiguel Ojeda } 3342808c999fSMiguel Ojeda } 3343808c999fSMiguel Ojeda 3344808c999fSMiguel Ojeda #[cfg(feature = "full")] 3345808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3346808c999fSMiguel Ojeda impl ToTokens for ExprAwait { to_tokens(&self, tokens: &mut TokenStream)3347808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3348808c999fSMiguel Ojeda print_expr_await(self, tokens, FixupContext::NONE); 3349808c999fSMiguel Ojeda } 3350808c999fSMiguel Ojeda } 3351808c999fSMiguel Ojeda 3352808c999fSMiguel Ojeda #[cfg(feature = "full")] print_expr_await(e: &ExprAwait, tokens: &mut TokenStream, fixup: FixupContext)3353808c999fSMiguel Ojeda fn print_expr_await(e: &ExprAwait, tokens: &mut TokenStream, fixup: FixupContext) { 3354808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3355808c999fSMiguel Ojeda let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.base); 3356808c999fSMiguel Ojeda print_subexpression( 3357808c999fSMiguel Ojeda &e.base, 3358808c999fSMiguel Ojeda left_prec < Precedence::Unambiguous, 3359808c999fSMiguel Ojeda tokens, 3360808c999fSMiguel Ojeda left_fixup, 3361808c999fSMiguel Ojeda ); 3362808c999fSMiguel Ojeda e.dot_token.to_tokens(tokens); 3363808c999fSMiguel Ojeda e.await_token.to_tokens(tokens); 3364808c999fSMiguel Ojeda } 3365808c999fSMiguel Ojeda 3366808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3367808c999fSMiguel Ojeda impl ToTokens for ExprBinary { to_tokens(&self, tokens: &mut TokenStream)3368808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3369808c999fSMiguel Ojeda print_expr_binary(self, tokens, FixupContext::NONE); 3370808c999fSMiguel Ojeda } 3371808c999fSMiguel Ojeda } 3372808c999fSMiguel Ojeda print_expr_binary(e: &ExprBinary, tokens: &mut TokenStream, mut fixup: FixupContext)3373808c999fSMiguel Ojeda fn print_expr_binary(e: &ExprBinary, tokens: &mut TokenStream, mut fixup: FixupContext) { 3374808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3375808c999fSMiguel Ojeda 3376808c999fSMiguel Ojeda let needs_group = !e.attrs.is_empty(); 3377808c999fSMiguel Ojeda if needs_group { 3378808c999fSMiguel Ojeda fixup = FixupContext::NONE; 3379808c999fSMiguel Ojeda } 3380808c999fSMiguel Ojeda 3381808c999fSMiguel Ojeda let do_print_expr = |tokens: &mut TokenStream| { 3382808c999fSMiguel Ojeda let binop_prec = Precedence::of_binop(&e.op); 3383808c999fSMiguel Ojeda let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator( 3384808c999fSMiguel Ojeda &e.left, 3385808c999fSMiguel Ojeda #[cfg(feature = "full")] 3386808c999fSMiguel Ojeda match &e.op { 3387808c999fSMiguel Ojeda BinOp::Sub(_) 3388808c999fSMiguel Ojeda | BinOp::Mul(_) 3389808c999fSMiguel Ojeda | BinOp::And(_) 3390808c999fSMiguel Ojeda | BinOp::Or(_) 3391808c999fSMiguel Ojeda | BinOp::BitAnd(_) 3392808c999fSMiguel Ojeda | BinOp::BitOr(_) 3393808c999fSMiguel Ojeda | BinOp::Shl(_) 3394808c999fSMiguel Ojeda | BinOp::Lt(_) => true, 3395808c999fSMiguel Ojeda _ => false, 3396808c999fSMiguel Ojeda }, 3397808c999fSMiguel Ojeda match &e.op { 3398808c999fSMiguel Ojeda BinOp::Shl(_) | BinOp::Lt(_) => true, 3399808c999fSMiguel Ojeda _ => false, 3400808c999fSMiguel Ojeda }, 3401808c999fSMiguel Ojeda #[cfg(feature = "full")] 3402808c999fSMiguel Ojeda binop_prec, 3403808c999fSMiguel Ojeda ); 3404808c999fSMiguel Ojeda let left_needs_group = match binop_prec { 3405808c999fSMiguel Ojeda Precedence::Assign => left_prec <= Precedence::Range, 3406808c999fSMiguel Ojeda Precedence::Compare => left_prec <= binop_prec, 3407808c999fSMiguel Ojeda _ => left_prec < binop_prec, 3408808c999fSMiguel Ojeda }; 3409808c999fSMiguel Ojeda 3410808c999fSMiguel Ojeda let right_fixup = fixup.rightmost_subexpression_fixup( 3411808c999fSMiguel Ojeda #[cfg(feature = "full")] 3412808c999fSMiguel Ojeda false, 3413808c999fSMiguel Ojeda #[cfg(feature = "full")] 3414808c999fSMiguel Ojeda false, 3415808c999fSMiguel Ojeda #[cfg(feature = "full")] 3416808c999fSMiguel Ojeda binop_prec, 3417808c999fSMiguel Ojeda ); 3418808c999fSMiguel Ojeda let right_needs_group = binop_prec != Precedence::Assign 3419808c999fSMiguel Ojeda && right_fixup.rightmost_subexpression_precedence(&e.right) <= binop_prec; 3420808c999fSMiguel Ojeda 3421808c999fSMiguel Ojeda print_subexpression(&e.left, left_needs_group, tokens, left_fixup); 3422808c999fSMiguel Ojeda e.op.to_tokens(tokens); 3423808c999fSMiguel Ojeda print_subexpression(&e.right, right_needs_group, tokens, right_fixup); 3424808c999fSMiguel Ojeda }; 3425808c999fSMiguel Ojeda 3426808c999fSMiguel Ojeda if needs_group { 3427808c999fSMiguel Ojeda token::Paren::default().surround(tokens, do_print_expr); 3428808c999fSMiguel Ojeda } else { 3429808c999fSMiguel Ojeda do_print_expr(tokens); 3430808c999fSMiguel Ojeda } 3431808c999fSMiguel Ojeda } 3432808c999fSMiguel Ojeda 3433808c999fSMiguel Ojeda #[cfg(feature = "full")] 3434808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3435808c999fSMiguel Ojeda impl ToTokens for ExprBlock { to_tokens(&self, tokens: &mut TokenStream)3436808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3437808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3438808c999fSMiguel Ojeda self.label.to_tokens(tokens); 3439808c999fSMiguel Ojeda self.block.brace_token.surround(tokens, |tokens| { 3440808c999fSMiguel Ojeda inner_attrs_to_tokens(&self.attrs, tokens); 3441808c999fSMiguel Ojeda tokens.append_all(&self.block.stmts); 3442808c999fSMiguel Ojeda }); 3443808c999fSMiguel Ojeda } 3444808c999fSMiguel Ojeda } 3445808c999fSMiguel Ojeda 3446808c999fSMiguel Ojeda #[cfg(feature = "full")] 3447808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3448808c999fSMiguel Ojeda impl ToTokens for ExprBreak { to_tokens(&self, tokens: &mut TokenStream)3449808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3450808c999fSMiguel Ojeda print_expr_break(self, tokens, FixupContext::NONE); 3451808c999fSMiguel Ojeda } 3452808c999fSMiguel Ojeda } 3453808c999fSMiguel Ojeda 3454808c999fSMiguel Ojeda #[cfg(feature = "full")] print_expr_break(e: &ExprBreak, tokens: &mut TokenStream, fixup: FixupContext)3455808c999fSMiguel Ojeda fn print_expr_break(e: &ExprBreak, tokens: &mut TokenStream, fixup: FixupContext) { 3456808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3457808c999fSMiguel Ojeda e.break_token.to_tokens(tokens); 3458808c999fSMiguel Ojeda e.label.to_tokens(tokens); 3459808c999fSMiguel Ojeda if let Some(value) = &e.expr { 3460808c999fSMiguel Ojeda print_subexpression( 3461808c999fSMiguel Ojeda value, 3462808c999fSMiguel Ojeda // Parenthesize `break 'inner: loop { break 'inner 1 } + 1` 3463808c999fSMiguel Ojeda // ^---------------------------------^ 3464808c999fSMiguel Ojeda e.label.is_none() && classify::expr_leading_label(value), 3465808c999fSMiguel Ojeda tokens, 3466808c999fSMiguel Ojeda fixup.rightmost_subexpression_fixup(true, true, Precedence::Jump), 3467808c999fSMiguel Ojeda ); 3468808c999fSMiguel Ojeda } 3469808c999fSMiguel Ojeda } 3470808c999fSMiguel Ojeda 3471808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3472808c999fSMiguel Ojeda impl ToTokens for ExprCall { to_tokens(&self, tokens: &mut TokenStream)3473808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3474808c999fSMiguel Ojeda print_expr_call(self, tokens, FixupContext::NONE); 3475808c999fSMiguel Ojeda } 3476808c999fSMiguel Ojeda } 3477808c999fSMiguel Ojeda print_expr_call(e: &ExprCall, tokens: &mut TokenStream, fixup: FixupContext)3478808c999fSMiguel Ojeda fn print_expr_call(e: &ExprCall, tokens: &mut TokenStream, fixup: FixupContext) { 3479808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3480808c999fSMiguel Ojeda 3481808c999fSMiguel Ojeda let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator( 3482808c999fSMiguel Ojeda &e.func, 3483808c999fSMiguel Ojeda #[cfg(feature = "full")] 3484808c999fSMiguel Ojeda true, 3485808c999fSMiguel Ojeda false, 3486808c999fSMiguel Ojeda #[cfg(feature = "full")] 3487808c999fSMiguel Ojeda Precedence::Unambiguous, 3488808c999fSMiguel Ojeda ); 3489808c999fSMiguel Ojeda let needs_group = if let Expr::Field(func) = &*e.func { 3490808c999fSMiguel Ojeda func.member.is_named() 3491808c999fSMiguel Ojeda } else { 3492808c999fSMiguel Ojeda left_prec < Precedence::Unambiguous 3493808c999fSMiguel Ojeda }; 3494808c999fSMiguel Ojeda print_subexpression(&e.func, needs_group, tokens, left_fixup); 3495808c999fSMiguel Ojeda 3496808c999fSMiguel Ojeda e.paren_token.surround(tokens, |tokens| { 3497808c999fSMiguel Ojeda e.args.to_tokens(tokens); 3498808c999fSMiguel Ojeda }); 3499808c999fSMiguel Ojeda } 3500808c999fSMiguel Ojeda 3501808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3502808c999fSMiguel Ojeda impl ToTokens for ExprCast { to_tokens(&self, tokens: &mut TokenStream)3503808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3504808c999fSMiguel Ojeda print_expr_cast(self, tokens, FixupContext::NONE); 3505808c999fSMiguel Ojeda } 3506808c999fSMiguel Ojeda } 3507808c999fSMiguel Ojeda print_expr_cast(e: &ExprCast, tokens: &mut TokenStream, mut fixup: FixupContext)3508808c999fSMiguel Ojeda fn print_expr_cast(e: &ExprCast, tokens: &mut TokenStream, mut fixup: FixupContext) { 3509808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3510808c999fSMiguel Ojeda 3511808c999fSMiguel Ojeda let needs_group = !e.attrs.is_empty(); 3512808c999fSMiguel Ojeda if needs_group { 3513808c999fSMiguel Ojeda fixup = FixupContext::NONE; 3514808c999fSMiguel Ojeda } 3515808c999fSMiguel Ojeda 3516808c999fSMiguel Ojeda let do_print_expr = |tokens: &mut TokenStream| { 3517808c999fSMiguel Ojeda let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator( 3518808c999fSMiguel Ojeda &e.expr, 3519808c999fSMiguel Ojeda #[cfg(feature = "full")] 3520808c999fSMiguel Ojeda false, 3521808c999fSMiguel Ojeda false, 3522808c999fSMiguel Ojeda #[cfg(feature = "full")] 3523808c999fSMiguel Ojeda Precedence::Cast, 3524808c999fSMiguel Ojeda ); 3525808c999fSMiguel Ojeda print_subexpression(&e.expr, left_prec < Precedence::Cast, tokens, left_fixup); 3526808c999fSMiguel Ojeda e.as_token.to_tokens(tokens); 3527808c999fSMiguel Ojeda e.ty.to_tokens(tokens); 3528808c999fSMiguel Ojeda }; 3529808c999fSMiguel Ojeda 3530808c999fSMiguel Ojeda if needs_group { 3531808c999fSMiguel Ojeda token::Paren::default().surround(tokens, do_print_expr); 3532808c999fSMiguel Ojeda } else { 3533808c999fSMiguel Ojeda do_print_expr(tokens); 3534808c999fSMiguel Ojeda } 3535808c999fSMiguel Ojeda } 3536808c999fSMiguel Ojeda 3537808c999fSMiguel Ojeda #[cfg(feature = "full")] 3538808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3539808c999fSMiguel Ojeda impl ToTokens for ExprClosure { to_tokens(&self, tokens: &mut TokenStream)3540808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3541808c999fSMiguel Ojeda print_expr_closure(self, tokens, FixupContext::NONE); 3542808c999fSMiguel Ojeda } 3543808c999fSMiguel Ojeda } 3544808c999fSMiguel Ojeda 3545808c999fSMiguel Ojeda #[cfg(feature = "full")] print_expr_closure(e: &ExprClosure, tokens: &mut TokenStream, fixup: FixupContext)3546808c999fSMiguel Ojeda fn print_expr_closure(e: &ExprClosure, tokens: &mut TokenStream, fixup: FixupContext) { 3547808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3548808c999fSMiguel Ojeda e.lifetimes.to_tokens(tokens); 3549808c999fSMiguel Ojeda e.constness.to_tokens(tokens); 3550808c999fSMiguel Ojeda e.movability.to_tokens(tokens); 3551808c999fSMiguel Ojeda e.asyncness.to_tokens(tokens); 3552808c999fSMiguel Ojeda e.capture.to_tokens(tokens); 3553808c999fSMiguel Ojeda e.or1_token.to_tokens(tokens); 3554808c999fSMiguel Ojeda e.inputs.to_tokens(tokens); 3555808c999fSMiguel Ojeda e.or2_token.to_tokens(tokens); 3556808c999fSMiguel Ojeda e.output.to_tokens(tokens); 3557808c999fSMiguel Ojeda if matches!(e.output, ReturnType::Default) 3558808c999fSMiguel Ojeda || matches!(&*e.body, Expr::Block(body) if body.attrs.is_empty() && body.label.is_none()) 3559808c999fSMiguel Ojeda { 3560808c999fSMiguel Ojeda print_expr( 3561808c999fSMiguel Ojeda &e.body, 3562808c999fSMiguel Ojeda tokens, 3563808c999fSMiguel Ojeda fixup.rightmost_subexpression_fixup(false, false, Precedence::Jump), 3564808c999fSMiguel Ojeda ); 3565808c999fSMiguel Ojeda } else { 3566808c999fSMiguel Ojeda token::Brace::default().surround(tokens, |tokens| { 3567808c999fSMiguel Ojeda print_expr(&e.body, tokens, FixupContext::new_stmt()); 3568808c999fSMiguel Ojeda }); 3569808c999fSMiguel Ojeda } 3570808c999fSMiguel Ojeda } 3571808c999fSMiguel Ojeda 3572808c999fSMiguel Ojeda #[cfg(feature = "full")] 3573808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3574808c999fSMiguel Ojeda impl ToTokens for ExprConst { to_tokens(&self, tokens: &mut TokenStream)3575808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3576808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3577808c999fSMiguel Ojeda self.const_token.to_tokens(tokens); 3578808c999fSMiguel Ojeda self.block.brace_token.surround(tokens, |tokens| { 3579808c999fSMiguel Ojeda inner_attrs_to_tokens(&self.attrs, tokens); 3580808c999fSMiguel Ojeda tokens.append_all(&self.block.stmts); 3581808c999fSMiguel Ojeda }); 3582808c999fSMiguel Ojeda } 3583808c999fSMiguel Ojeda } 3584808c999fSMiguel Ojeda 3585808c999fSMiguel Ojeda #[cfg(feature = "full")] 3586808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3587808c999fSMiguel Ojeda impl ToTokens for ExprContinue { to_tokens(&self, tokens: &mut TokenStream)3588808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3589808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3590808c999fSMiguel Ojeda self.continue_token.to_tokens(tokens); 3591808c999fSMiguel Ojeda self.label.to_tokens(tokens); 3592808c999fSMiguel Ojeda } 3593808c999fSMiguel Ojeda } 3594808c999fSMiguel Ojeda 3595808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3596808c999fSMiguel Ojeda impl ToTokens for ExprField { to_tokens(&self, tokens: &mut TokenStream)3597808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3598808c999fSMiguel Ojeda print_expr_field(self, tokens, FixupContext::NONE); 3599808c999fSMiguel Ojeda } 3600808c999fSMiguel Ojeda } 3601808c999fSMiguel Ojeda print_expr_field(e: &ExprField, tokens: &mut TokenStream, fixup: FixupContext)3602808c999fSMiguel Ojeda fn print_expr_field(e: &ExprField, tokens: &mut TokenStream, fixup: FixupContext) { 3603808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3604808c999fSMiguel Ojeda let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.base); 3605808c999fSMiguel Ojeda print_subexpression( 3606808c999fSMiguel Ojeda &e.base, 3607808c999fSMiguel Ojeda left_prec < Precedence::Unambiguous, 3608808c999fSMiguel Ojeda tokens, 3609808c999fSMiguel Ojeda left_fixup, 3610808c999fSMiguel Ojeda ); 3611808c999fSMiguel Ojeda e.dot_token.to_tokens(tokens); 3612808c999fSMiguel Ojeda e.member.to_tokens(tokens); 3613808c999fSMiguel Ojeda } 3614808c999fSMiguel Ojeda 3615808c999fSMiguel Ojeda #[cfg(feature = "full")] 3616808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3617808c999fSMiguel Ojeda impl ToTokens for ExprForLoop { to_tokens(&self, tokens: &mut TokenStream)3618808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3619808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3620808c999fSMiguel Ojeda self.label.to_tokens(tokens); 3621808c999fSMiguel Ojeda self.for_token.to_tokens(tokens); 3622808c999fSMiguel Ojeda self.pat.to_tokens(tokens); 3623808c999fSMiguel Ojeda self.in_token.to_tokens(tokens); 3624808c999fSMiguel Ojeda print_expr(&self.expr, tokens, FixupContext::new_condition()); 3625808c999fSMiguel Ojeda self.body.brace_token.surround(tokens, |tokens| { 3626808c999fSMiguel Ojeda inner_attrs_to_tokens(&self.attrs, tokens); 3627808c999fSMiguel Ojeda tokens.append_all(&self.body.stmts); 3628808c999fSMiguel Ojeda }); 3629808c999fSMiguel Ojeda } 3630808c999fSMiguel Ojeda } 3631808c999fSMiguel Ojeda 3632808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3633808c999fSMiguel Ojeda impl ToTokens for ExprGroup { to_tokens(&self, tokens: &mut TokenStream)3634808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3635808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3636808c999fSMiguel Ojeda self.group_token.surround(tokens, |tokens| { 3637808c999fSMiguel Ojeda self.expr.to_tokens(tokens); 3638808c999fSMiguel Ojeda }); 3639808c999fSMiguel Ojeda } 3640808c999fSMiguel Ojeda } 3641808c999fSMiguel Ojeda 3642808c999fSMiguel Ojeda #[cfg(feature = "full")] 3643808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3644808c999fSMiguel Ojeda impl ToTokens for ExprIf { to_tokens(&self, tokens: &mut TokenStream)3645808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3646808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3647808c999fSMiguel Ojeda 3648808c999fSMiguel Ojeda let mut expr = self; 3649808c999fSMiguel Ojeda loop { 3650808c999fSMiguel Ojeda expr.if_token.to_tokens(tokens); 3651808c999fSMiguel Ojeda print_expr(&expr.cond, tokens, FixupContext::new_condition()); 3652808c999fSMiguel Ojeda expr.then_branch.to_tokens(tokens); 3653808c999fSMiguel Ojeda 3654808c999fSMiguel Ojeda let (else_token, else_) = match &expr.else_branch { 3655808c999fSMiguel Ojeda Some(else_branch) => else_branch, 3656808c999fSMiguel Ojeda None => break, 3657808c999fSMiguel Ojeda }; 3658808c999fSMiguel Ojeda 3659808c999fSMiguel Ojeda else_token.to_tokens(tokens); 3660808c999fSMiguel Ojeda match &**else_ { 3661808c999fSMiguel Ojeda Expr::If(next) => { 3662808c999fSMiguel Ojeda expr = next; 3663808c999fSMiguel Ojeda } 3664808c999fSMiguel Ojeda Expr::Block(last) => { 3665808c999fSMiguel Ojeda last.to_tokens(tokens); 3666808c999fSMiguel Ojeda break; 3667808c999fSMiguel Ojeda } 3668808c999fSMiguel Ojeda // If this is not one of the valid expressions to exist in 3669808c999fSMiguel Ojeda // an else clause, wrap it in a block. 3670808c999fSMiguel Ojeda other => { 3671808c999fSMiguel Ojeda token::Brace::default().surround(tokens, |tokens| { 3672808c999fSMiguel Ojeda print_expr(other, tokens, FixupContext::new_stmt()); 3673808c999fSMiguel Ojeda }); 3674808c999fSMiguel Ojeda break; 3675808c999fSMiguel Ojeda } 3676808c999fSMiguel Ojeda } 3677808c999fSMiguel Ojeda } 3678808c999fSMiguel Ojeda } 3679808c999fSMiguel Ojeda } 3680808c999fSMiguel Ojeda 3681808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3682808c999fSMiguel Ojeda impl ToTokens for ExprIndex { to_tokens(&self, tokens: &mut TokenStream)3683808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3684808c999fSMiguel Ojeda print_expr_index(self, tokens, FixupContext::NONE); 3685808c999fSMiguel Ojeda } 3686808c999fSMiguel Ojeda } 3687808c999fSMiguel Ojeda print_expr_index(e: &ExprIndex, tokens: &mut TokenStream, fixup: FixupContext)3688808c999fSMiguel Ojeda fn print_expr_index(e: &ExprIndex, tokens: &mut TokenStream, fixup: FixupContext) { 3689808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3690808c999fSMiguel Ojeda let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator( 3691808c999fSMiguel Ojeda &e.expr, 3692808c999fSMiguel Ojeda #[cfg(feature = "full")] 3693808c999fSMiguel Ojeda true, 3694808c999fSMiguel Ojeda false, 3695808c999fSMiguel Ojeda #[cfg(feature = "full")] 3696808c999fSMiguel Ojeda Precedence::Unambiguous, 3697808c999fSMiguel Ojeda ); 3698808c999fSMiguel Ojeda print_subexpression( 3699808c999fSMiguel Ojeda &e.expr, 3700808c999fSMiguel Ojeda left_prec < Precedence::Unambiguous, 3701808c999fSMiguel Ojeda tokens, 3702808c999fSMiguel Ojeda left_fixup, 3703808c999fSMiguel Ojeda ); 3704808c999fSMiguel Ojeda e.bracket_token.surround(tokens, |tokens| { 3705808c999fSMiguel Ojeda e.index.to_tokens(tokens); 3706808c999fSMiguel Ojeda }); 3707808c999fSMiguel Ojeda } 3708808c999fSMiguel Ojeda 3709808c999fSMiguel Ojeda #[cfg(feature = "full")] 3710808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3711808c999fSMiguel Ojeda impl ToTokens for ExprInfer { to_tokens(&self, tokens: &mut TokenStream)3712808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3713808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3714808c999fSMiguel Ojeda self.underscore_token.to_tokens(tokens); 3715808c999fSMiguel Ojeda } 3716808c999fSMiguel Ojeda } 3717808c999fSMiguel Ojeda 3718808c999fSMiguel Ojeda #[cfg(feature = "full")] 3719808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3720808c999fSMiguel Ojeda impl ToTokens for ExprLet { to_tokens(&self, tokens: &mut TokenStream)3721808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3722808c999fSMiguel Ojeda print_expr_let(self, tokens, FixupContext::NONE); 3723808c999fSMiguel Ojeda } 3724808c999fSMiguel Ojeda } 3725808c999fSMiguel Ojeda 3726808c999fSMiguel Ojeda #[cfg(feature = "full")] print_expr_let(e: &ExprLet, tokens: &mut TokenStream, fixup: FixupContext)3727808c999fSMiguel Ojeda fn print_expr_let(e: &ExprLet, tokens: &mut TokenStream, fixup: FixupContext) { 3728808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3729808c999fSMiguel Ojeda e.let_token.to_tokens(tokens); 3730808c999fSMiguel Ojeda e.pat.to_tokens(tokens); 3731808c999fSMiguel Ojeda e.eq_token.to_tokens(tokens); 3732808c999fSMiguel Ojeda let (right_prec, right_fixup) = fixup.rightmost_subexpression(&e.expr, Precedence::Let); 3733808c999fSMiguel Ojeda print_subexpression(&e.expr, right_prec < Precedence::Let, tokens, right_fixup); 3734808c999fSMiguel Ojeda } 3735808c999fSMiguel Ojeda 3736808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3737808c999fSMiguel Ojeda impl ToTokens for ExprLit { to_tokens(&self, tokens: &mut TokenStream)3738808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3739808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3740808c999fSMiguel Ojeda self.lit.to_tokens(tokens); 3741808c999fSMiguel Ojeda } 3742808c999fSMiguel Ojeda } 3743808c999fSMiguel Ojeda 3744808c999fSMiguel Ojeda #[cfg(feature = "full")] 3745808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3746808c999fSMiguel Ojeda impl ToTokens for ExprLoop { to_tokens(&self, tokens: &mut TokenStream)3747808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3748808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3749808c999fSMiguel Ojeda self.label.to_tokens(tokens); 3750808c999fSMiguel Ojeda self.loop_token.to_tokens(tokens); 3751808c999fSMiguel Ojeda self.body.brace_token.surround(tokens, |tokens| { 3752808c999fSMiguel Ojeda inner_attrs_to_tokens(&self.attrs, tokens); 3753808c999fSMiguel Ojeda tokens.append_all(&self.body.stmts); 3754808c999fSMiguel Ojeda }); 3755808c999fSMiguel Ojeda } 3756808c999fSMiguel Ojeda } 3757808c999fSMiguel Ojeda 3758808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3759808c999fSMiguel Ojeda impl ToTokens for ExprMacro { to_tokens(&self, tokens: &mut TokenStream)3760808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3761808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3762808c999fSMiguel Ojeda self.mac.to_tokens(tokens); 3763808c999fSMiguel Ojeda } 3764808c999fSMiguel Ojeda } 3765808c999fSMiguel Ojeda 3766808c999fSMiguel Ojeda #[cfg(feature = "full")] 3767808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3768808c999fSMiguel Ojeda impl ToTokens for ExprMatch { to_tokens(&self, tokens: &mut TokenStream)3769808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3770808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3771808c999fSMiguel Ojeda self.match_token.to_tokens(tokens); 3772808c999fSMiguel Ojeda print_expr(&self.expr, tokens, FixupContext::new_condition()); 3773808c999fSMiguel Ojeda self.brace_token.surround(tokens, |tokens| { 3774808c999fSMiguel Ojeda inner_attrs_to_tokens(&self.attrs, tokens); 3775808c999fSMiguel Ojeda for (i, arm) in self.arms.iter().enumerate() { 3776808c999fSMiguel Ojeda arm.to_tokens(tokens); 3777808c999fSMiguel Ojeda // Ensure that we have a comma after a non-block arm, except 3778808c999fSMiguel Ojeda // for the last one. 3779808c999fSMiguel Ojeda let is_last = i == self.arms.len() - 1; 3780808c999fSMiguel Ojeda if !is_last 3781808c999fSMiguel Ojeda && classify::requires_comma_to_be_match_arm(&arm.body) 3782808c999fSMiguel Ojeda && arm.comma.is_none() 3783808c999fSMiguel Ojeda { 3784808c999fSMiguel Ojeda <Token![,]>::default().to_tokens(tokens); 3785808c999fSMiguel Ojeda } 3786808c999fSMiguel Ojeda } 3787808c999fSMiguel Ojeda }); 3788808c999fSMiguel Ojeda } 3789808c999fSMiguel Ojeda } 3790808c999fSMiguel Ojeda 3791808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3792808c999fSMiguel Ojeda impl ToTokens for ExprMethodCall { to_tokens(&self, tokens: &mut TokenStream)3793808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3794808c999fSMiguel Ojeda print_expr_method_call(self, tokens, FixupContext::NONE); 3795808c999fSMiguel Ojeda } 3796808c999fSMiguel Ojeda } 3797808c999fSMiguel Ojeda print_expr_method_call(e: &ExprMethodCall, tokens: &mut TokenStream, fixup: FixupContext)3798808c999fSMiguel Ojeda fn print_expr_method_call(e: &ExprMethodCall, tokens: &mut TokenStream, fixup: FixupContext) { 3799808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3800808c999fSMiguel Ojeda let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.receiver); 3801808c999fSMiguel Ojeda print_subexpression( 3802808c999fSMiguel Ojeda &e.receiver, 3803808c999fSMiguel Ojeda left_prec < Precedence::Unambiguous, 3804808c999fSMiguel Ojeda tokens, 3805808c999fSMiguel Ojeda left_fixup, 3806808c999fSMiguel Ojeda ); 3807808c999fSMiguel Ojeda e.dot_token.to_tokens(tokens); 3808808c999fSMiguel Ojeda e.method.to_tokens(tokens); 3809808c999fSMiguel Ojeda if let Some(turbofish) = &e.turbofish { 3810808c999fSMiguel Ojeda path::printing::print_angle_bracketed_generic_arguments( 3811808c999fSMiguel Ojeda tokens, 3812808c999fSMiguel Ojeda turbofish, 3813808c999fSMiguel Ojeda PathStyle::Expr, 3814808c999fSMiguel Ojeda ); 3815808c999fSMiguel Ojeda } 3816808c999fSMiguel Ojeda e.paren_token.surround(tokens, |tokens| { 3817808c999fSMiguel Ojeda e.args.to_tokens(tokens); 3818808c999fSMiguel Ojeda }); 3819808c999fSMiguel Ojeda } 3820808c999fSMiguel Ojeda 3821808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3822808c999fSMiguel Ojeda impl ToTokens for ExprParen { to_tokens(&self, tokens: &mut TokenStream)3823808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3824808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3825808c999fSMiguel Ojeda self.paren_token.surround(tokens, |tokens| { 3826808c999fSMiguel Ojeda self.expr.to_tokens(tokens); 3827808c999fSMiguel Ojeda }); 3828808c999fSMiguel Ojeda } 3829808c999fSMiguel Ojeda } 3830808c999fSMiguel Ojeda 3831808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3832808c999fSMiguel Ojeda impl ToTokens for ExprPath { to_tokens(&self, tokens: &mut TokenStream)3833808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3834808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3835808c999fSMiguel Ojeda path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::Expr); 3836808c999fSMiguel Ojeda } 3837808c999fSMiguel Ojeda } 3838808c999fSMiguel Ojeda 3839808c999fSMiguel Ojeda #[cfg(feature = "full")] 3840808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3841808c999fSMiguel Ojeda impl ToTokens for ExprRange { to_tokens(&self, tokens: &mut TokenStream)3842808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3843808c999fSMiguel Ojeda print_expr_range(self, tokens, FixupContext::NONE); 3844808c999fSMiguel Ojeda } 3845808c999fSMiguel Ojeda } 3846808c999fSMiguel Ojeda 3847808c999fSMiguel Ojeda #[cfg(feature = "full")] print_expr_range(e: &ExprRange, tokens: &mut TokenStream, mut fixup: FixupContext)3848808c999fSMiguel Ojeda fn print_expr_range(e: &ExprRange, tokens: &mut TokenStream, mut fixup: FixupContext) { 3849808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3850808c999fSMiguel Ojeda 3851808c999fSMiguel Ojeda let needs_group = !e.attrs.is_empty(); 3852808c999fSMiguel Ojeda if needs_group { 3853808c999fSMiguel Ojeda fixup = FixupContext::NONE; 3854808c999fSMiguel Ojeda } 3855808c999fSMiguel Ojeda 3856808c999fSMiguel Ojeda let do_print_expr = |tokens: &mut TokenStream| { 3857808c999fSMiguel Ojeda if let Some(start) = &e.start { 3858808c999fSMiguel Ojeda let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator( 3859808c999fSMiguel Ojeda start, 3860808c999fSMiguel Ojeda true, 3861808c999fSMiguel Ojeda false, 3862808c999fSMiguel Ojeda Precedence::Range, 3863808c999fSMiguel Ojeda ); 3864808c999fSMiguel Ojeda print_subexpression(start, left_prec <= Precedence::Range, tokens, left_fixup); 3865808c999fSMiguel Ojeda } 3866808c999fSMiguel Ojeda e.limits.to_tokens(tokens); 3867808c999fSMiguel Ojeda if let Some(end) = &e.end { 3868808c999fSMiguel Ojeda let right_fixup = 3869808c999fSMiguel Ojeda fixup.rightmost_subexpression_fixup(false, true, Precedence::Range); 3870808c999fSMiguel Ojeda let right_prec = right_fixup.rightmost_subexpression_precedence(end); 3871808c999fSMiguel Ojeda print_subexpression(end, right_prec <= Precedence::Range, tokens, right_fixup); 3872808c999fSMiguel Ojeda } 3873808c999fSMiguel Ojeda }; 3874808c999fSMiguel Ojeda 3875808c999fSMiguel Ojeda if needs_group { 3876808c999fSMiguel Ojeda token::Paren::default().surround(tokens, do_print_expr); 3877808c999fSMiguel Ojeda } else { 3878808c999fSMiguel Ojeda do_print_expr(tokens); 3879808c999fSMiguel Ojeda } 3880808c999fSMiguel Ojeda } 3881808c999fSMiguel Ojeda 3882808c999fSMiguel Ojeda #[cfg(feature = "full")] 3883808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3884808c999fSMiguel Ojeda impl ToTokens for ExprRawAddr { to_tokens(&self, tokens: &mut TokenStream)3885808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3886808c999fSMiguel Ojeda print_expr_raw_addr(self, tokens, FixupContext::NONE); 3887808c999fSMiguel Ojeda } 3888808c999fSMiguel Ojeda } 3889808c999fSMiguel Ojeda 3890808c999fSMiguel Ojeda #[cfg(feature = "full")] print_expr_raw_addr(e: &ExprRawAddr, tokens: &mut TokenStream, fixup: FixupContext)3891808c999fSMiguel Ojeda fn print_expr_raw_addr(e: &ExprRawAddr, tokens: &mut TokenStream, fixup: FixupContext) { 3892808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3893808c999fSMiguel Ojeda e.and_token.to_tokens(tokens); 3894808c999fSMiguel Ojeda e.raw.to_tokens(tokens); 3895808c999fSMiguel Ojeda e.mutability.to_tokens(tokens); 3896808c999fSMiguel Ojeda let (right_prec, right_fixup) = fixup.rightmost_subexpression(&e.expr, Precedence::Prefix); 3897808c999fSMiguel Ojeda print_subexpression( 3898808c999fSMiguel Ojeda &e.expr, 3899808c999fSMiguel Ojeda right_prec < Precedence::Prefix, 3900808c999fSMiguel Ojeda tokens, 3901808c999fSMiguel Ojeda right_fixup, 3902808c999fSMiguel Ojeda ); 3903808c999fSMiguel Ojeda } 3904808c999fSMiguel Ojeda 3905808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3906808c999fSMiguel Ojeda impl ToTokens for ExprReference { to_tokens(&self, tokens: &mut TokenStream)3907808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3908808c999fSMiguel Ojeda print_expr_reference(self, tokens, FixupContext::NONE); 3909808c999fSMiguel Ojeda } 3910808c999fSMiguel Ojeda } 3911808c999fSMiguel Ojeda print_expr_reference(e: &ExprReference, tokens: &mut TokenStream, fixup: FixupContext)3912808c999fSMiguel Ojeda fn print_expr_reference(e: &ExprReference, tokens: &mut TokenStream, fixup: FixupContext) { 3913808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3914808c999fSMiguel Ojeda e.and_token.to_tokens(tokens); 3915808c999fSMiguel Ojeda e.mutability.to_tokens(tokens); 3916808c999fSMiguel Ojeda let (right_prec, right_fixup) = fixup.rightmost_subexpression( 3917808c999fSMiguel Ojeda &e.expr, 3918808c999fSMiguel Ojeda #[cfg(feature = "full")] 3919808c999fSMiguel Ojeda Precedence::Prefix, 3920808c999fSMiguel Ojeda ); 3921808c999fSMiguel Ojeda print_subexpression( 3922808c999fSMiguel Ojeda &e.expr, 3923808c999fSMiguel Ojeda right_prec < Precedence::Prefix, 3924808c999fSMiguel Ojeda tokens, 3925808c999fSMiguel Ojeda right_fixup, 3926808c999fSMiguel Ojeda ); 3927808c999fSMiguel Ojeda } 3928808c999fSMiguel Ojeda 3929808c999fSMiguel Ojeda #[cfg(feature = "full")] 3930808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3931808c999fSMiguel Ojeda impl ToTokens for ExprRepeat { to_tokens(&self, tokens: &mut TokenStream)3932808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3933808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3934808c999fSMiguel Ojeda self.bracket_token.surround(tokens, |tokens| { 3935808c999fSMiguel Ojeda self.expr.to_tokens(tokens); 3936808c999fSMiguel Ojeda self.semi_token.to_tokens(tokens); 3937808c999fSMiguel Ojeda self.len.to_tokens(tokens); 3938808c999fSMiguel Ojeda }); 3939808c999fSMiguel Ojeda } 3940808c999fSMiguel Ojeda } 3941808c999fSMiguel Ojeda 3942808c999fSMiguel Ojeda #[cfg(feature = "full")] 3943808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3944808c999fSMiguel Ojeda impl ToTokens for ExprReturn { to_tokens(&self, tokens: &mut TokenStream)3945808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3946808c999fSMiguel Ojeda print_expr_return(self, tokens, FixupContext::NONE); 3947808c999fSMiguel Ojeda } 3948808c999fSMiguel Ojeda } 3949808c999fSMiguel Ojeda 3950808c999fSMiguel Ojeda #[cfg(feature = "full")] print_expr_return(e: &ExprReturn, tokens: &mut TokenStream, fixup: FixupContext)3951808c999fSMiguel Ojeda fn print_expr_return(e: &ExprReturn, tokens: &mut TokenStream, fixup: FixupContext) { 3952808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3953808c999fSMiguel Ojeda e.return_token.to_tokens(tokens); 3954808c999fSMiguel Ojeda if let Some(expr) = &e.expr { 3955808c999fSMiguel Ojeda print_expr( 3956808c999fSMiguel Ojeda expr, 3957808c999fSMiguel Ojeda tokens, 3958808c999fSMiguel Ojeda fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump), 3959808c999fSMiguel Ojeda ); 3960808c999fSMiguel Ojeda } 3961808c999fSMiguel Ojeda } 3962808c999fSMiguel Ojeda 3963808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3964808c999fSMiguel Ojeda impl ToTokens for ExprStruct { to_tokens(&self, tokens: &mut TokenStream)3965808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3966808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 3967808c999fSMiguel Ojeda path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::Expr); 3968808c999fSMiguel Ojeda self.brace_token.surround(tokens, |tokens| { 3969808c999fSMiguel Ojeda self.fields.to_tokens(tokens); 3970808c999fSMiguel Ojeda if let Some(dot2_token) = &self.dot2_token { 3971808c999fSMiguel Ojeda dot2_token.to_tokens(tokens); 3972808c999fSMiguel Ojeda } else if self.rest.is_some() { 3973808c999fSMiguel Ojeda Token).to_tokens(tokens); 3974808c999fSMiguel Ojeda } 3975808c999fSMiguel Ojeda self.rest.to_tokens(tokens); 3976808c999fSMiguel Ojeda }); 3977808c999fSMiguel Ojeda } 3978808c999fSMiguel Ojeda } 3979808c999fSMiguel Ojeda 3980808c999fSMiguel Ojeda #[cfg(feature = "full")] 3981808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 3982808c999fSMiguel Ojeda impl ToTokens for ExprTry { to_tokens(&self, tokens: &mut TokenStream)3983808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 3984808c999fSMiguel Ojeda print_expr_try(self, tokens, FixupContext::NONE); 3985808c999fSMiguel Ojeda } 3986808c999fSMiguel Ojeda } 3987808c999fSMiguel Ojeda 3988808c999fSMiguel Ojeda #[cfg(feature = "full")] print_expr_try(e: &ExprTry, tokens: &mut TokenStream, fixup: FixupContext)3989808c999fSMiguel Ojeda fn print_expr_try(e: &ExprTry, tokens: &mut TokenStream, fixup: FixupContext) { 3990808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 3991808c999fSMiguel Ojeda let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.expr); 3992808c999fSMiguel Ojeda print_subexpression( 3993808c999fSMiguel Ojeda &e.expr, 3994808c999fSMiguel Ojeda left_prec < Precedence::Unambiguous, 3995808c999fSMiguel Ojeda tokens, 3996808c999fSMiguel Ojeda left_fixup, 3997808c999fSMiguel Ojeda ); 3998808c999fSMiguel Ojeda e.question_token.to_tokens(tokens); 3999808c999fSMiguel Ojeda } 4000808c999fSMiguel Ojeda 4001808c999fSMiguel Ojeda #[cfg(feature = "full")] 4002808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4003808c999fSMiguel Ojeda impl ToTokens for ExprTryBlock { to_tokens(&self, tokens: &mut TokenStream)4004808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4005808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 4006808c999fSMiguel Ojeda self.try_token.to_tokens(tokens); 4007808c999fSMiguel Ojeda self.block.to_tokens(tokens); 4008808c999fSMiguel Ojeda } 4009808c999fSMiguel Ojeda } 4010808c999fSMiguel Ojeda 4011808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4012808c999fSMiguel Ojeda impl ToTokens for ExprTuple { to_tokens(&self, tokens: &mut TokenStream)4013808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4014808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 4015808c999fSMiguel Ojeda self.paren_token.surround(tokens, |tokens| { 4016808c999fSMiguel Ojeda self.elems.to_tokens(tokens); 4017808c999fSMiguel Ojeda // If we only have one argument, we need a trailing comma to 4018808c999fSMiguel Ojeda // distinguish ExprTuple from ExprParen. 4019808c999fSMiguel Ojeda if self.elems.len() == 1 && !self.elems.trailing_punct() { 4020808c999fSMiguel Ojeda <Token![,]>::default().to_tokens(tokens); 4021808c999fSMiguel Ojeda } 4022808c999fSMiguel Ojeda }); 4023808c999fSMiguel Ojeda } 4024808c999fSMiguel Ojeda } 4025808c999fSMiguel Ojeda 4026808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4027808c999fSMiguel Ojeda impl ToTokens for ExprUnary { to_tokens(&self, tokens: &mut TokenStream)4028808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4029808c999fSMiguel Ojeda print_expr_unary(self, tokens, FixupContext::NONE); 4030808c999fSMiguel Ojeda } 4031808c999fSMiguel Ojeda } 4032808c999fSMiguel Ojeda print_expr_unary(e: &ExprUnary, tokens: &mut TokenStream, fixup: FixupContext)4033808c999fSMiguel Ojeda fn print_expr_unary(e: &ExprUnary, tokens: &mut TokenStream, fixup: FixupContext) { 4034808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 4035808c999fSMiguel Ojeda e.op.to_tokens(tokens); 4036808c999fSMiguel Ojeda let (right_prec, right_fixup) = fixup.rightmost_subexpression( 4037808c999fSMiguel Ojeda &e.expr, 4038808c999fSMiguel Ojeda #[cfg(feature = "full")] 4039808c999fSMiguel Ojeda Precedence::Prefix, 4040808c999fSMiguel Ojeda ); 4041808c999fSMiguel Ojeda print_subexpression( 4042808c999fSMiguel Ojeda &e.expr, 4043808c999fSMiguel Ojeda right_prec < Precedence::Prefix, 4044808c999fSMiguel Ojeda tokens, 4045808c999fSMiguel Ojeda right_fixup, 4046808c999fSMiguel Ojeda ); 4047808c999fSMiguel Ojeda } 4048808c999fSMiguel Ojeda 4049808c999fSMiguel Ojeda #[cfg(feature = "full")] 4050808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4051808c999fSMiguel Ojeda impl ToTokens for ExprUnsafe { to_tokens(&self, tokens: &mut TokenStream)4052808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4053808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 4054808c999fSMiguel Ojeda self.unsafe_token.to_tokens(tokens); 4055808c999fSMiguel Ojeda self.block.brace_token.surround(tokens, |tokens| { 4056808c999fSMiguel Ojeda inner_attrs_to_tokens(&self.attrs, tokens); 4057808c999fSMiguel Ojeda tokens.append_all(&self.block.stmts); 4058808c999fSMiguel Ojeda }); 4059808c999fSMiguel Ojeda } 4060808c999fSMiguel Ojeda } 4061808c999fSMiguel Ojeda 4062808c999fSMiguel Ojeda #[cfg(feature = "full")] 4063808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4064808c999fSMiguel Ojeda impl ToTokens for ExprWhile { to_tokens(&self, tokens: &mut TokenStream)4065808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4066808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 4067808c999fSMiguel Ojeda self.label.to_tokens(tokens); 4068808c999fSMiguel Ojeda self.while_token.to_tokens(tokens); 4069808c999fSMiguel Ojeda print_expr(&self.cond, tokens, FixupContext::new_condition()); 4070808c999fSMiguel Ojeda self.body.brace_token.surround(tokens, |tokens| { 4071808c999fSMiguel Ojeda inner_attrs_to_tokens(&self.attrs, tokens); 4072808c999fSMiguel Ojeda tokens.append_all(&self.body.stmts); 4073808c999fSMiguel Ojeda }); 4074808c999fSMiguel Ojeda } 4075808c999fSMiguel Ojeda } 4076808c999fSMiguel Ojeda 4077808c999fSMiguel Ojeda #[cfg(feature = "full")] 4078808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4079808c999fSMiguel Ojeda impl ToTokens for ExprYield { to_tokens(&self, tokens: &mut TokenStream)4080808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4081808c999fSMiguel Ojeda print_expr_yield(self, tokens, FixupContext::NONE); 4082808c999fSMiguel Ojeda } 4083808c999fSMiguel Ojeda } 4084808c999fSMiguel Ojeda 4085808c999fSMiguel Ojeda #[cfg(feature = "full")] print_expr_yield(e: &ExprYield, tokens: &mut TokenStream, fixup: FixupContext)4086808c999fSMiguel Ojeda fn print_expr_yield(e: &ExprYield, tokens: &mut TokenStream, fixup: FixupContext) { 4087808c999fSMiguel Ojeda outer_attrs_to_tokens(&e.attrs, tokens); 4088808c999fSMiguel Ojeda e.yield_token.to_tokens(tokens); 4089808c999fSMiguel Ojeda if let Some(expr) = &e.expr { 4090808c999fSMiguel Ojeda print_expr( 4091808c999fSMiguel Ojeda expr, 4092808c999fSMiguel Ojeda tokens, 4093808c999fSMiguel Ojeda fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump), 4094808c999fSMiguel Ojeda ); 4095808c999fSMiguel Ojeda } 4096808c999fSMiguel Ojeda } 4097808c999fSMiguel Ojeda 4098808c999fSMiguel Ojeda #[cfg(feature = "full")] 4099808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4100808c999fSMiguel Ojeda impl ToTokens for Arm { to_tokens(&self, tokens: &mut TokenStream)4101808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4102808c999fSMiguel Ojeda tokens.append_all(&self.attrs); 4103808c999fSMiguel Ojeda self.pat.to_tokens(tokens); 4104808c999fSMiguel Ojeda if let Some((if_token, guard)) = &self.guard { 4105808c999fSMiguel Ojeda if_token.to_tokens(tokens); 4106808c999fSMiguel Ojeda guard.to_tokens(tokens); 4107808c999fSMiguel Ojeda } 4108808c999fSMiguel Ojeda self.fat_arrow_token.to_tokens(tokens); 4109808c999fSMiguel Ojeda print_expr(&self.body, tokens, FixupContext::new_match_arm()); 4110808c999fSMiguel Ojeda self.comma.to_tokens(tokens); 4111808c999fSMiguel Ojeda } 4112808c999fSMiguel Ojeda } 4113808c999fSMiguel Ojeda 4114808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4115808c999fSMiguel Ojeda impl ToTokens for FieldValue { to_tokens(&self, tokens: &mut TokenStream)4116808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4117808c999fSMiguel Ojeda outer_attrs_to_tokens(&self.attrs, tokens); 4118808c999fSMiguel Ojeda self.member.to_tokens(tokens); 4119808c999fSMiguel Ojeda if let Some(colon_token) = &self.colon_token { 4120808c999fSMiguel Ojeda colon_token.to_tokens(tokens); 4121808c999fSMiguel Ojeda self.expr.to_tokens(tokens); 4122808c999fSMiguel Ojeda } 4123808c999fSMiguel Ojeda } 4124808c999fSMiguel Ojeda } 4125808c999fSMiguel Ojeda 4126808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4127808c999fSMiguel Ojeda impl ToTokens for Index { to_tokens(&self, tokens: &mut TokenStream)4128808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4129808c999fSMiguel Ojeda let mut lit = Literal::i64_unsuffixed(i64::from(self.index)); 4130808c999fSMiguel Ojeda lit.set_span(self.span); 4131808c999fSMiguel Ojeda tokens.append(lit); 4132808c999fSMiguel Ojeda } 4133808c999fSMiguel Ojeda } 4134808c999fSMiguel Ojeda 4135808c999fSMiguel Ojeda #[cfg(feature = "full")] 4136808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4137808c999fSMiguel Ojeda impl ToTokens for Label { to_tokens(&self, tokens: &mut TokenStream)4138808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4139808c999fSMiguel Ojeda self.name.to_tokens(tokens); 4140808c999fSMiguel Ojeda self.colon_token.to_tokens(tokens); 4141808c999fSMiguel Ojeda } 4142808c999fSMiguel Ojeda } 4143808c999fSMiguel Ojeda 4144808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4145808c999fSMiguel Ojeda impl ToTokens for Member { to_tokens(&self, tokens: &mut TokenStream)4146808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4147808c999fSMiguel Ojeda match self { 4148808c999fSMiguel Ojeda Member::Named(ident) => ident.to_tokens(tokens), 4149808c999fSMiguel Ojeda Member::Unnamed(index) => index.to_tokens(tokens), 4150808c999fSMiguel Ojeda } 4151808c999fSMiguel Ojeda } 4152808c999fSMiguel Ojeda } 4153808c999fSMiguel Ojeda 4154808c999fSMiguel Ojeda #[cfg(feature = "full")] 4155808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4156808c999fSMiguel Ojeda impl ToTokens for RangeLimits { to_tokens(&self, tokens: &mut TokenStream)4157808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4158808c999fSMiguel Ojeda match self { 4159808c999fSMiguel Ojeda RangeLimits::HalfOpen(t) => t.to_tokens(tokens), 4160808c999fSMiguel Ojeda RangeLimits::Closed(t) => t.to_tokens(tokens), 4161808c999fSMiguel Ojeda } 4162808c999fSMiguel Ojeda } 4163808c999fSMiguel Ojeda } 4164808c999fSMiguel Ojeda 4165808c999fSMiguel Ojeda #[cfg(feature = "full")] 4166808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 4167808c999fSMiguel Ojeda impl ToTokens for PointerMutability { to_tokens(&self, tokens: &mut TokenStream)4168808c999fSMiguel Ojeda fn to_tokens(&self, tokens: &mut TokenStream) { 4169808c999fSMiguel Ojeda match self { 4170808c999fSMiguel Ojeda PointerMutability::Const(const_token) => const_token.to_tokens(tokens), 4171808c999fSMiguel Ojeda PointerMutability::Mut(mut_token) => mut_token.to_tokens(tokens), 4172808c999fSMiguel Ojeda } 4173808c999fSMiguel Ojeda } 4174808c999fSMiguel Ojeda } 4175808c999fSMiguel Ojeda } 4176