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