1fad3a1d3Sopenharmony_ci#![allow(clippy::single_element_loop, clippy::uninlined_format_args)] 2fad3a1d3Sopenharmony_ci 3fad3a1d3Sopenharmony_ci#[macro_use] 4fad3a1d3Sopenharmony_cimod macros; 5fad3a1d3Sopenharmony_ci 6fad3a1d3Sopenharmony_ciuse proc_macro2::{Delimiter, Group}; 7fad3a1d3Sopenharmony_ciuse quote::{quote, ToTokens as _}; 8fad3a1d3Sopenharmony_ciuse syn::punctuated::Punctuated; 9fad3a1d3Sopenharmony_ciuse syn::{parse_quote, token, Expr, ExprRange, ExprTuple, Stmt, Token}; 10fad3a1d3Sopenharmony_ci 11fad3a1d3Sopenharmony_ci#[test] 12fad3a1d3Sopenharmony_cifn test_expr_parse() { 13fad3a1d3Sopenharmony_ci let tokens = quote!(..100u32); 14fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 15fad3a1d3Sopenharmony_ci Expr::Range { 16fad3a1d3Sopenharmony_ci limits: RangeLimits::HalfOpen, 17fad3a1d3Sopenharmony_ci end: Some(Expr::Lit { 18fad3a1d3Sopenharmony_ci lit: 100u32, 19fad3a1d3Sopenharmony_ci }), 20fad3a1d3Sopenharmony_ci } 21fad3a1d3Sopenharmony_ci "###); 22fad3a1d3Sopenharmony_ci 23fad3a1d3Sopenharmony_ci let tokens = quote!(..100u32); 24fad3a1d3Sopenharmony_ci snapshot!(tokens as ExprRange, @r###" 25fad3a1d3Sopenharmony_ci ExprRange { 26fad3a1d3Sopenharmony_ci limits: RangeLimits::HalfOpen, 27fad3a1d3Sopenharmony_ci end: Some(Expr::Lit { 28fad3a1d3Sopenharmony_ci lit: 100u32, 29fad3a1d3Sopenharmony_ci }), 30fad3a1d3Sopenharmony_ci } 31fad3a1d3Sopenharmony_ci "###); 32fad3a1d3Sopenharmony_ci} 33fad3a1d3Sopenharmony_ci 34fad3a1d3Sopenharmony_ci#[test] 35fad3a1d3Sopenharmony_cifn test_await() { 36fad3a1d3Sopenharmony_ci // Must not parse as Expr::Field. 37fad3a1d3Sopenharmony_ci let tokens = quote!(fut.await); 38fad3a1d3Sopenharmony_ci 39fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 40fad3a1d3Sopenharmony_ci Expr::Await { 41fad3a1d3Sopenharmony_ci base: Expr::Path { 42fad3a1d3Sopenharmony_ci path: Path { 43fad3a1d3Sopenharmony_ci segments: [ 44fad3a1d3Sopenharmony_ci PathSegment { 45fad3a1d3Sopenharmony_ci ident: "fut", 46fad3a1d3Sopenharmony_ci }, 47fad3a1d3Sopenharmony_ci ], 48fad3a1d3Sopenharmony_ci }, 49fad3a1d3Sopenharmony_ci }, 50fad3a1d3Sopenharmony_ci } 51fad3a1d3Sopenharmony_ci "###); 52fad3a1d3Sopenharmony_ci} 53fad3a1d3Sopenharmony_ci 54fad3a1d3Sopenharmony_ci#[rustfmt::skip] 55fad3a1d3Sopenharmony_ci#[test] 56fad3a1d3Sopenharmony_cifn test_tuple_multi_index() { 57fad3a1d3Sopenharmony_ci let expected = snapshot!("tuple.0.0" as Expr, @r###" 58fad3a1d3Sopenharmony_ci Expr::Field { 59fad3a1d3Sopenharmony_ci base: Expr::Field { 60fad3a1d3Sopenharmony_ci base: Expr::Path { 61fad3a1d3Sopenharmony_ci path: Path { 62fad3a1d3Sopenharmony_ci segments: [ 63fad3a1d3Sopenharmony_ci PathSegment { 64fad3a1d3Sopenharmony_ci ident: "tuple", 65fad3a1d3Sopenharmony_ci }, 66fad3a1d3Sopenharmony_ci ], 67fad3a1d3Sopenharmony_ci }, 68fad3a1d3Sopenharmony_ci }, 69fad3a1d3Sopenharmony_ci member: Member::Unnamed(Index { 70fad3a1d3Sopenharmony_ci index: 0, 71fad3a1d3Sopenharmony_ci }), 72fad3a1d3Sopenharmony_ci }, 73fad3a1d3Sopenharmony_ci member: Member::Unnamed(Index { 74fad3a1d3Sopenharmony_ci index: 0, 75fad3a1d3Sopenharmony_ci }), 76fad3a1d3Sopenharmony_ci } 77fad3a1d3Sopenharmony_ci "###); 78fad3a1d3Sopenharmony_ci 79fad3a1d3Sopenharmony_ci for &input in &[ 80fad3a1d3Sopenharmony_ci "tuple .0.0", 81fad3a1d3Sopenharmony_ci "tuple. 0.0", 82fad3a1d3Sopenharmony_ci "tuple.0 .0", 83fad3a1d3Sopenharmony_ci "tuple.0. 0", 84fad3a1d3Sopenharmony_ci "tuple . 0 . 0", 85fad3a1d3Sopenharmony_ci ] { 86fad3a1d3Sopenharmony_ci assert_eq!(expected, syn::parse_str(input).unwrap()); 87fad3a1d3Sopenharmony_ci } 88fad3a1d3Sopenharmony_ci 89fad3a1d3Sopenharmony_ci for tokens in [ 90fad3a1d3Sopenharmony_ci quote!(tuple.0.0), 91fad3a1d3Sopenharmony_ci quote!(tuple .0.0), 92fad3a1d3Sopenharmony_ci quote!(tuple. 0.0), 93fad3a1d3Sopenharmony_ci quote!(tuple.0 .0), 94fad3a1d3Sopenharmony_ci quote!(tuple.0. 0), 95fad3a1d3Sopenharmony_ci quote!(tuple . 0 . 0), 96fad3a1d3Sopenharmony_ci ] { 97fad3a1d3Sopenharmony_ci assert_eq!(expected, syn::parse2(tokens).unwrap()); 98fad3a1d3Sopenharmony_ci } 99fad3a1d3Sopenharmony_ci} 100fad3a1d3Sopenharmony_ci 101fad3a1d3Sopenharmony_ci#[test] 102fad3a1d3Sopenharmony_cifn test_macro_variable_func() { 103fad3a1d3Sopenharmony_ci // mimics the token stream corresponding to `$fn()` 104fad3a1d3Sopenharmony_ci let path = Group::new(Delimiter::None, quote!(f)); 105fad3a1d3Sopenharmony_ci let tokens = quote!(#path()); 106fad3a1d3Sopenharmony_ci 107fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 108fad3a1d3Sopenharmony_ci Expr::Call { 109fad3a1d3Sopenharmony_ci func: Expr::Group { 110fad3a1d3Sopenharmony_ci expr: Expr::Path { 111fad3a1d3Sopenharmony_ci path: Path { 112fad3a1d3Sopenharmony_ci segments: [ 113fad3a1d3Sopenharmony_ci PathSegment { 114fad3a1d3Sopenharmony_ci ident: "f", 115fad3a1d3Sopenharmony_ci }, 116fad3a1d3Sopenharmony_ci ], 117fad3a1d3Sopenharmony_ci }, 118fad3a1d3Sopenharmony_ci }, 119fad3a1d3Sopenharmony_ci }, 120fad3a1d3Sopenharmony_ci } 121fad3a1d3Sopenharmony_ci "###); 122fad3a1d3Sopenharmony_ci 123fad3a1d3Sopenharmony_ci let path = Group::new(Delimiter::None, quote! { #[inside] f }); 124fad3a1d3Sopenharmony_ci let tokens = quote!(#[outside] #path()); 125fad3a1d3Sopenharmony_ci 126fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 127fad3a1d3Sopenharmony_ci Expr::Call { 128fad3a1d3Sopenharmony_ci attrs: [ 129fad3a1d3Sopenharmony_ci Attribute { 130fad3a1d3Sopenharmony_ci style: AttrStyle::Outer, 131fad3a1d3Sopenharmony_ci meta: Meta::Path { 132fad3a1d3Sopenharmony_ci segments: [ 133fad3a1d3Sopenharmony_ci PathSegment { 134fad3a1d3Sopenharmony_ci ident: "outside", 135fad3a1d3Sopenharmony_ci }, 136fad3a1d3Sopenharmony_ci ], 137fad3a1d3Sopenharmony_ci }, 138fad3a1d3Sopenharmony_ci }, 139fad3a1d3Sopenharmony_ci ], 140fad3a1d3Sopenharmony_ci func: Expr::Group { 141fad3a1d3Sopenharmony_ci expr: Expr::Path { 142fad3a1d3Sopenharmony_ci attrs: [ 143fad3a1d3Sopenharmony_ci Attribute { 144fad3a1d3Sopenharmony_ci style: AttrStyle::Outer, 145fad3a1d3Sopenharmony_ci meta: Meta::Path { 146fad3a1d3Sopenharmony_ci segments: [ 147fad3a1d3Sopenharmony_ci PathSegment { 148fad3a1d3Sopenharmony_ci ident: "inside", 149fad3a1d3Sopenharmony_ci }, 150fad3a1d3Sopenharmony_ci ], 151fad3a1d3Sopenharmony_ci }, 152fad3a1d3Sopenharmony_ci }, 153fad3a1d3Sopenharmony_ci ], 154fad3a1d3Sopenharmony_ci path: Path { 155fad3a1d3Sopenharmony_ci segments: [ 156fad3a1d3Sopenharmony_ci PathSegment { 157fad3a1d3Sopenharmony_ci ident: "f", 158fad3a1d3Sopenharmony_ci }, 159fad3a1d3Sopenharmony_ci ], 160fad3a1d3Sopenharmony_ci }, 161fad3a1d3Sopenharmony_ci }, 162fad3a1d3Sopenharmony_ci }, 163fad3a1d3Sopenharmony_ci } 164fad3a1d3Sopenharmony_ci "###); 165fad3a1d3Sopenharmony_ci} 166fad3a1d3Sopenharmony_ci 167fad3a1d3Sopenharmony_ci#[test] 168fad3a1d3Sopenharmony_cifn test_macro_variable_macro() { 169fad3a1d3Sopenharmony_ci // mimics the token stream corresponding to `$macro!()` 170fad3a1d3Sopenharmony_ci let mac = Group::new(Delimiter::None, quote!(m)); 171fad3a1d3Sopenharmony_ci let tokens = quote!(#mac!()); 172fad3a1d3Sopenharmony_ci 173fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 174fad3a1d3Sopenharmony_ci Expr::Macro { 175fad3a1d3Sopenharmony_ci mac: Macro { 176fad3a1d3Sopenharmony_ci path: Path { 177fad3a1d3Sopenharmony_ci segments: [ 178fad3a1d3Sopenharmony_ci PathSegment { 179fad3a1d3Sopenharmony_ci ident: "m", 180fad3a1d3Sopenharmony_ci }, 181fad3a1d3Sopenharmony_ci ], 182fad3a1d3Sopenharmony_ci }, 183fad3a1d3Sopenharmony_ci delimiter: MacroDelimiter::Paren, 184fad3a1d3Sopenharmony_ci tokens: TokenStream(``), 185fad3a1d3Sopenharmony_ci }, 186fad3a1d3Sopenharmony_ci } 187fad3a1d3Sopenharmony_ci "###); 188fad3a1d3Sopenharmony_ci} 189fad3a1d3Sopenharmony_ci 190fad3a1d3Sopenharmony_ci#[test] 191fad3a1d3Sopenharmony_cifn test_macro_variable_struct() { 192fad3a1d3Sopenharmony_ci // mimics the token stream corresponding to `$struct {}` 193fad3a1d3Sopenharmony_ci let s = Group::new(Delimiter::None, quote! { S }); 194fad3a1d3Sopenharmony_ci let tokens = quote!(#s {}); 195fad3a1d3Sopenharmony_ci 196fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 197fad3a1d3Sopenharmony_ci Expr::Struct { 198fad3a1d3Sopenharmony_ci path: Path { 199fad3a1d3Sopenharmony_ci segments: [ 200fad3a1d3Sopenharmony_ci PathSegment { 201fad3a1d3Sopenharmony_ci ident: "S", 202fad3a1d3Sopenharmony_ci }, 203fad3a1d3Sopenharmony_ci ], 204fad3a1d3Sopenharmony_ci }, 205fad3a1d3Sopenharmony_ci } 206fad3a1d3Sopenharmony_ci "###); 207fad3a1d3Sopenharmony_ci} 208fad3a1d3Sopenharmony_ci 209fad3a1d3Sopenharmony_ci#[test] 210fad3a1d3Sopenharmony_cifn test_macro_variable_unary() { 211fad3a1d3Sopenharmony_ci // mimics the token stream corresponding to `$expr.method()` where expr is `&self` 212fad3a1d3Sopenharmony_ci let inner = Group::new(Delimiter::None, quote!(&self)); 213fad3a1d3Sopenharmony_ci let tokens = quote!(#inner.method()); 214fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 215fad3a1d3Sopenharmony_ci Expr::MethodCall { 216fad3a1d3Sopenharmony_ci receiver: Expr::Group { 217fad3a1d3Sopenharmony_ci expr: Expr::Reference { 218fad3a1d3Sopenharmony_ci expr: Expr::Path { 219fad3a1d3Sopenharmony_ci path: Path { 220fad3a1d3Sopenharmony_ci segments: [ 221fad3a1d3Sopenharmony_ci PathSegment { 222fad3a1d3Sopenharmony_ci ident: "self", 223fad3a1d3Sopenharmony_ci }, 224fad3a1d3Sopenharmony_ci ], 225fad3a1d3Sopenharmony_ci }, 226fad3a1d3Sopenharmony_ci }, 227fad3a1d3Sopenharmony_ci }, 228fad3a1d3Sopenharmony_ci }, 229fad3a1d3Sopenharmony_ci method: "method", 230fad3a1d3Sopenharmony_ci } 231fad3a1d3Sopenharmony_ci "###); 232fad3a1d3Sopenharmony_ci} 233fad3a1d3Sopenharmony_ci 234fad3a1d3Sopenharmony_ci#[test] 235fad3a1d3Sopenharmony_cifn test_macro_variable_match_arm() { 236fad3a1d3Sopenharmony_ci // mimics the token stream corresponding to `match v { _ => $expr }` 237fad3a1d3Sopenharmony_ci let expr = Group::new(Delimiter::None, quote! { #[a] () }); 238fad3a1d3Sopenharmony_ci let tokens = quote!(match v { _ => #expr }); 239fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 240fad3a1d3Sopenharmony_ci Expr::Match { 241fad3a1d3Sopenharmony_ci expr: Expr::Path { 242fad3a1d3Sopenharmony_ci path: Path { 243fad3a1d3Sopenharmony_ci segments: [ 244fad3a1d3Sopenharmony_ci PathSegment { 245fad3a1d3Sopenharmony_ci ident: "v", 246fad3a1d3Sopenharmony_ci }, 247fad3a1d3Sopenharmony_ci ], 248fad3a1d3Sopenharmony_ci }, 249fad3a1d3Sopenharmony_ci }, 250fad3a1d3Sopenharmony_ci arms: [ 251fad3a1d3Sopenharmony_ci Arm { 252fad3a1d3Sopenharmony_ci pat: Pat::Wild, 253fad3a1d3Sopenharmony_ci body: Expr::Group { 254fad3a1d3Sopenharmony_ci expr: Expr::Tuple { 255fad3a1d3Sopenharmony_ci attrs: [ 256fad3a1d3Sopenharmony_ci Attribute { 257fad3a1d3Sopenharmony_ci style: AttrStyle::Outer, 258fad3a1d3Sopenharmony_ci meta: Meta::Path { 259fad3a1d3Sopenharmony_ci segments: [ 260fad3a1d3Sopenharmony_ci PathSegment { 261fad3a1d3Sopenharmony_ci ident: "a", 262fad3a1d3Sopenharmony_ci }, 263fad3a1d3Sopenharmony_ci ], 264fad3a1d3Sopenharmony_ci }, 265fad3a1d3Sopenharmony_ci }, 266fad3a1d3Sopenharmony_ci ], 267fad3a1d3Sopenharmony_ci }, 268fad3a1d3Sopenharmony_ci }, 269fad3a1d3Sopenharmony_ci }, 270fad3a1d3Sopenharmony_ci ], 271fad3a1d3Sopenharmony_ci } 272fad3a1d3Sopenharmony_ci "###); 273fad3a1d3Sopenharmony_ci 274fad3a1d3Sopenharmony_ci let expr = Group::new(Delimiter::None, quote!(loop {} + 1)); 275fad3a1d3Sopenharmony_ci let tokens = quote!(match v { _ => #expr }); 276fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 277fad3a1d3Sopenharmony_ci Expr::Match { 278fad3a1d3Sopenharmony_ci expr: Expr::Path { 279fad3a1d3Sopenharmony_ci path: Path { 280fad3a1d3Sopenharmony_ci segments: [ 281fad3a1d3Sopenharmony_ci PathSegment { 282fad3a1d3Sopenharmony_ci ident: "v", 283fad3a1d3Sopenharmony_ci }, 284fad3a1d3Sopenharmony_ci ], 285fad3a1d3Sopenharmony_ci }, 286fad3a1d3Sopenharmony_ci }, 287fad3a1d3Sopenharmony_ci arms: [ 288fad3a1d3Sopenharmony_ci Arm { 289fad3a1d3Sopenharmony_ci pat: Pat::Wild, 290fad3a1d3Sopenharmony_ci body: Expr::Group { 291fad3a1d3Sopenharmony_ci expr: Expr::Binary { 292fad3a1d3Sopenharmony_ci left: Expr::Loop { 293fad3a1d3Sopenharmony_ci body: Block { 294fad3a1d3Sopenharmony_ci stmts: [], 295fad3a1d3Sopenharmony_ci }, 296fad3a1d3Sopenharmony_ci }, 297fad3a1d3Sopenharmony_ci op: BinOp::Add, 298fad3a1d3Sopenharmony_ci right: Expr::Lit { 299fad3a1d3Sopenharmony_ci lit: 1, 300fad3a1d3Sopenharmony_ci }, 301fad3a1d3Sopenharmony_ci }, 302fad3a1d3Sopenharmony_ci }, 303fad3a1d3Sopenharmony_ci }, 304fad3a1d3Sopenharmony_ci ], 305fad3a1d3Sopenharmony_ci } 306fad3a1d3Sopenharmony_ci "###); 307fad3a1d3Sopenharmony_ci} 308fad3a1d3Sopenharmony_ci 309fad3a1d3Sopenharmony_ci// https://github.com/dtolnay/syn/issues/1019 310fad3a1d3Sopenharmony_ci#[test] 311fad3a1d3Sopenharmony_cifn test_closure_vs_rangefull() { 312fad3a1d3Sopenharmony_ci #[rustfmt::skip] // rustfmt bug: https://github.com/rust-lang/rustfmt/issues/4808 313fad3a1d3Sopenharmony_ci let tokens = quote!(|| .. .method()); 314fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 315fad3a1d3Sopenharmony_ci Expr::MethodCall { 316fad3a1d3Sopenharmony_ci receiver: Expr::Closure { 317fad3a1d3Sopenharmony_ci output: ReturnType::Default, 318fad3a1d3Sopenharmony_ci body: Expr::Range { 319fad3a1d3Sopenharmony_ci limits: RangeLimits::HalfOpen, 320fad3a1d3Sopenharmony_ci }, 321fad3a1d3Sopenharmony_ci }, 322fad3a1d3Sopenharmony_ci method: "method", 323fad3a1d3Sopenharmony_ci } 324fad3a1d3Sopenharmony_ci "###); 325fad3a1d3Sopenharmony_ci} 326fad3a1d3Sopenharmony_ci 327fad3a1d3Sopenharmony_ci#[test] 328fad3a1d3Sopenharmony_cifn test_postfix_operator_after_cast() { 329fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("|| &x as T[0]").unwrap_err(); 330fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("|| () as ()()").unwrap_err(); 331fad3a1d3Sopenharmony_ci} 332fad3a1d3Sopenharmony_ci 333fad3a1d3Sopenharmony_ci#[test] 334fad3a1d3Sopenharmony_cifn test_ranges() { 335fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("..").unwrap(); 336fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("..hi").unwrap(); 337fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("lo..").unwrap(); 338fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("lo..hi").unwrap(); 339fad3a1d3Sopenharmony_ci 340fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("..=").unwrap_err(); 341fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("..=hi").unwrap(); 342fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("lo..=").unwrap_err(); 343fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("lo..=hi").unwrap(); 344fad3a1d3Sopenharmony_ci 345fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("...").unwrap_err(); 346fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("...hi").unwrap_err(); 347fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("lo...").unwrap_err(); 348fad3a1d3Sopenharmony_ci syn::parse_str::<Expr>("lo...hi").unwrap_err(); 349fad3a1d3Sopenharmony_ci} 350fad3a1d3Sopenharmony_ci 351fad3a1d3Sopenharmony_ci#[test] 352fad3a1d3Sopenharmony_cifn test_ambiguous_label() { 353fad3a1d3Sopenharmony_ci for stmt in [ 354fad3a1d3Sopenharmony_ci quote! { 355fad3a1d3Sopenharmony_ci return 'label: loop { break 'label 42; }; 356fad3a1d3Sopenharmony_ci }, 357fad3a1d3Sopenharmony_ci quote! { 358fad3a1d3Sopenharmony_ci break ('label: loop { break 'label 42; }); 359fad3a1d3Sopenharmony_ci }, 360fad3a1d3Sopenharmony_ci quote! { 361fad3a1d3Sopenharmony_ci break 1 + 'label: loop { break 'label 42; }; 362fad3a1d3Sopenharmony_ci }, 363fad3a1d3Sopenharmony_ci quote! { 364fad3a1d3Sopenharmony_ci break 'outer 'inner: loop { break 'inner 42; }; 365fad3a1d3Sopenharmony_ci }, 366fad3a1d3Sopenharmony_ci ] { 367fad3a1d3Sopenharmony_ci syn::parse2::<Stmt>(stmt).unwrap(); 368fad3a1d3Sopenharmony_ci } 369fad3a1d3Sopenharmony_ci 370fad3a1d3Sopenharmony_ci for stmt in [ 371fad3a1d3Sopenharmony_ci // Parentheses required. See https://github.com/rust-lang/rust/pull/87026. 372fad3a1d3Sopenharmony_ci quote! { 373fad3a1d3Sopenharmony_ci break 'label: loop { break 'label 42; }; 374fad3a1d3Sopenharmony_ci }, 375fad3a1d3Sopenharmony_ci ] { 376fad3a1d3Sopenharmony_ci syn::parse2::<Stmt>(stmt).unwrap_err(); 377fad3a1d3Sopenharmony_ci } 378fad3a1d3Sopenharmony_ci} 379fad3a1d3Sopenharmony_ci 380fad3a1d3Sopenharmony_ci#[test] 381fad3a1d3Sopenharmony_cifn test_extended_interpolated_path() { 382fad3a1d3Sopenharmony_ci let path = Group::new(Delimiter::None, quote!(a::b)); 383fad3a1d3Sopenharmony_ci 384fad3a1d3Sopenharmony_ci let tokens = quote!(if #path {}); 385fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 386fad3a1d3Sopenharmony_ci Expr::If { 387fad3a1d3Sopenharmony_ci cond: Expr::Group { 388fad3a1d3Sopenharmony_ci expr: Expr::Path { 389fad3a1d3Sopenharmony_ci path: Path { 390fad3a1d3Sopenharmony_ci segments: [ 391fad3a1d3Sopenharmony_ci PathSegment { 392fad3a1d3Sopenharmony_ci ident: "a", 393fad3a1d3Sopenharmony_ci }, 394fad3a1d3Sopenharmony_ci Token![::], 395fad3a1d3Sopenharmony_ci PathSegment { 396fad3a1d3Sopenharmony_ci ident: "b", 397fad3a1d3Sopenharmony_ci }, 398fad3a1d3Sopenharmony_ci ], 399fad3a1d3Sopenharmony_ci }, 400fad3a1d3Sopenharmony_ci }, 401fad3a1d3Sopenharmony_ci }, 402fad3a1d3Sopenharmony_ci then_branch: Block { 403fad3a1d3Sopenharmony_ci stmts: [], 404fad3a1d3Sopenharmony_ci }, 405fad3a1d3Sopenharmony_ci } 406fad3a1d3Sopenharmony_ci "###); 407fad3a1d3Sopenharmony_ci 408fad3a1d3Sopenharmony_ci let tokens = quote!(#path {}); 409fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 410fad3a1d3Sopenharmony_ci Expr::Struct { 411fad3a1d3Sopenharmony_ci path: Path { 412fad3a1d3Sopenharmony_ci segments: [ 413fad3a1d3Sopenharmony_ci PathSegment { 414fad3a1d3Sopenharmony_ci ident: "a", 415fad3a1d3Sopenharmony_ci }, 416fad3a1d3Sopenharmony_ci Token![::], 417fad3a1d3Sopenharmony_ci PathSegment { 418fad3a1d3Sopenharmony_ci ident: "b", 419fad3a1d3Sopenharmony_ci }, 420fad3a1d3Sopenharmony_ci ], 421fad3a1d3Sopenharmony_ci }, 422fad3a1d3Sopenharmony_ci } 423fad3a1d3Sopenharmony_ci "###); 424fad3a1d3Sopenharmony_ci 425fad3a1d3Sopenharmony_ci let tokens = quote!(#path :: c); 426fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 427fad3a1d3Sopenharmony_ci Expr::Path { 428fad3a1d3Sopenharmony_ci path: Path { 429fad3a1d3Sopenharmony_ci segments: [ 430fad3a1d3Sopenharmony_ci PathSegment { 431fad3a1d3Sopenharmony_ci ident: "a", 432fad3a1d3Sopenharmony_ci }, 433fad3a1d3Sopenharmony_ci Token![::], 434fad3a1d3Sopenharmony_ci PathSegment { 435fad3a1d3Sopenharmony_ci ident: "b", 436fad3a1d3Sopenharmony_ci }, 437fad3a1d3Sopenharmony_ci Token![::], 438fad3a1d3Sopenharmony_ci PathSegment { 439fad3a1d3Sopenharmony_ci ident: "c", 440fad3a1d3Sopenharmony_ci }, 441fad3a1d3Sopenharmony_ci ], 442fad3a1d3Sopenharmony_ci }, 443fad3a1d3Sopenharmony_ci } 444fad3a1d3Sopenharmony_ci "###); 445fad3a1d3Sopenharmony_ci 446fad3a1d3Sopenharmony_ci let nested = Group::new(Delimiter::None, quote!(a::b || true)); 447fad3a1d3Sopenharmony_ci let tokens = quote!(if #nested && false {}); 448fad3a1d3Sopenharmony_ci snapshot!(tokens as Expr, @r###" 449fad3a1d3Sopenharmony_ci Expr::If { 450fad3a1d3Sopenharmony_ci cond: Expr::Binary { 451fad3a1d3Sopenharmony_ci left: Expr::Group { 452fad3a1d3Sopenharmony_ci expr: Expr::Binary { 453fad3a1d3Sopenharmony_ci left: Expr::Path { 454fad3a1d3Sopenharmony_ci path: Path { 455fad3a1d3Sopenharmony_ci segments: [ 456fad3a1d3Sopenharmony_ci PathSegment { 457fad3a1d3Sopenharmony_ci ident: "a", 458fad3a1d3Sopenharmony_ci }, 459fad3a1d3Sopenharmony_ci Token![::], 460fad3a1d3Sopenharmony_ci PathSegment { 461fad3a1d3Sopenharmony_ci ident: "b", 462fad3a1d3Sopenharmony_ci }, 463fad3a1d3Sopenharmony_ci ], 464fad3a1d3Sopenharmony_ci }, 465fad3a1d3Sopenharmony_ci }, 466fad3a1d3Sopenharmony_ci op: BinOp::Or, 467fad3a1d3Sopenharmony_ci right: Expr::Lit { 468fad3a1d3Sopenharmony_ci lit: Lit::Bool { 469fad3a1d3Sopenharmony_ci value: true, 470fad3a1d3Sopenharmony_ci }, 471fad3a1d3Sopenharmony_ci }, 472fad3a1d3Sopenharmony_ci }, 473fad3a1d3Sopenharmony_ci }, 474fad3a1d3Sopenharmony_ci op: BinOp::And, 475fad3a1d3Sopenharmony_ci right: Expr::Lit { 476fad3a1d3Sopenharmony_ci lit: Lit::Bool { 477fad3a1d3Sopenharmony_ci value: false, 478fad3a1d3Sopenharmony_ci }, 479fad3a1d3Sopenharmony_ci }, 480fad3a1d3Sopenharmony_ci }, 481fad3a1d3Sopenharmony_ci then_branch: Block { 482fad3a1d3Sopenharmony_ci stmts: [], 483fad3a1d3Sopenharmony_ci }, 484fad3a1d3Sopenharmony_ci } 485fad3a1d3Sopenharmony_ci "###); 486fad3a1d3Sopenharmony_ci} 487fad3a1d3Sopenharmony_ci 488fad3a1d3Sopenharmony_ci#[test] 489fad3a1d3Sopenharmony_cifn test_tuple_comma() { 490fad3a1d3Sopenharmony_ci let mut expr = ExprTuple { 491fad3a1d3Sopenharmony_ci attrs: Vec::new(), 492fad3a1d3Sopenharmony_ci paren_token: token::Paren::default(), 493fad3a1d3Sopenharmony_ci elems: Punctuated::new(), 494fad3a1d3Sopenharmony_ci }; 495fad3a1d3Sopenharmony_ci snapshot!(expr.to_token_stream() as Expr, @"Expr::Tuple"); 496fad3a1d3Sopenharmony_ci 497fad3a1d3Sopenharmony_ci expr.elems.push_value(parse_quote!(continue)); 498fad3a1d3Sopenharmony_ci // Must not parse to Expr::Paren 499fad3a1d3Sopenharmony_ci snapshot!(expr.to_token_stream() as Expr, @r###" 500fad3a1d3Sopenharmony_ci Expr::Tuple { 501fad3a1d3Sopenharmony_ci elems: [ 502fad3a1d3Sopenharmony_ci Expr::Continue, 503fad3a1d3Sopenharmony_ci Token![,], 504fad3a1d3Sopenharmony_ci ], 505fad3a1d3Sopenharmony_ci } 506fad3a1d3Sopenharmony_ci "###); 507fad3a1d3Sopenharmony_ci 508fad3a1d3Sopenharmony_ci expr.elems.push_punct(<Token![,]>::default()); 509fad3a1d3Sopenharmony_ci snapshot!(expr.to_token_stream() as Expr, @r###" 510fad3a1d3Sopenharmony_ci Expr::Tuple { 511fad3a1d3Sopenharmony_ci elems: [ 512fad3a1d3Sopenharmony_ci Expr::Continue, 513fad3a1d3Sopenharmony_ci Token![,], 514fad3a1d3Sopenharmony_ci ], 515fad3a1d3Sopenharmony_ci } 516fad3a1d3Sopenharmony_ci "###); 517fad3a1d3Sopenharmony_ci 518fad3a1d3Sopenharmony_ci expr.elems.push_value(parse_quote!(continue)); 519fad3a1d3Sopenharmony_ci snapshot!(expr.to_token_stream() as Expr, @r###" 520fad3a1d3Sopenharmony_ci Expr::Tuple { 521fad3a1d3Sopenharmony_ci elems: [ 522fad3a1d3Sopenharmony_ci Expr::Continue, 523fad3a1d3Sopenharmony_ci Token![,], 524fad3a1d3Sopenharmony_ci Expr::Continue, 525fad3a1d3Sopenharmony_ci ], 526fad3a1d3Sopenharmony_ci } 527fad3a1d3Sopenharmony_ci "###); 528fad3a1d3Sopenharmony_ci 529fad3a1d3Sopenharmony_ci expr.elems.push_punct(<Token![,]>::default()); 530fad3a1d3Sopenharmony_ci snapshot!(expr.to_token_stream() as Expr, @r###" 531fad3a1d3Sopenharmony_ci Expr::Tuple { 532fad3a1d3Sopenharmony_ci elems: [ 533fad3a1d3Sopenharmony_ci Expr::Continue, 534fad3a1d3Sopenharmony_ci Token![,], 535fad3a1d3Sopenharmony_ci Expr::Continue, 536fad3a1d3Sopenharmony_ci Token![,], 537fad3a1d3Sopenharmony_ci ], 538fad3a1d3Sopenharmony_ci } 539fad3a1d3Sopenharmony_ci "###); 540fad3a1d3Sopenharmony_ci} 541