1fad3a1d3Sopenharmony_ci#![allow( 2fad3a1d3Sopenharmony_ci clippy::assertions_on_result_states, 3fad3a1d3Sopenharmony_ci clippy::non_ascii_literal, 4fad3a1d3Sopenharmony_ci clippy::uninlined_format_args 5fad3a1d3Sopenharmony_ci)] 6fad3a1d3Sopenharmony_ci 7fad3a1d3Sopenharmony_ci#[macro_use] 8fad3a1d3Sopenharmony_cimod macros; 9fad3a1d3Sopenharmony_ci 10fad3a1d3Sopenharmony_ciuse proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree}; 11fad3a1d3Sopenharmony_ciuse quote::{quote, ToTokens as _}; 12fad3a1d3Sopenharmony_ciuse syn::parse::Parser as _; 13fad3a1d3Sopenharmony_ciuse syn::{Block, Stmt}; 14fad3a1d3Sopenharmony_ci 15fad3a1d3Sopenharmony_ci#[test] 16fad3a1d3Sopenharmony_cifn test_raw_operator() { 17fad3a1d3Sopenharmony_ci let stmt = syn::parse_str::<Stmt>("let _ = &raw const x;").unwrap(); 18fad3a1d3Sopenharmony_ci 19fad3a1d3Sopenharmony_ci snapshot!(stmt, @r###" 20fad3a1d3Sopenharmony_ci Stmt::Local { 21fad3a1d3Sopenharmony_ci pat: Pat::Wild, 22fad3a1d3Sopenharmony_ci init: Some(LocalInit { 23fad3a1d3Sopenharmony_ci expr: Expr::Verbatim(`& raw const x`), 24fad3a1d3Sopenharmony_ci }), 25fad3a1d3Sopenharmony_ci } 26fad3a1d3Sopenharmony_ci "###); 27fad3a1d3Sopenharmony_ci} 28fad3a1d3Sopenharmony_ci 29fad3a1d3Sopenharmony_ci#[test] 30fad3a1d3Sopenharmony_cifn test_raw_variable() { 31fad3a1d3Sopenharmony_ci let stmt = syn::parse_str::<Stmt>("let _ = &raw;").unwrap(); 32fad3a1d3Sopenharmony_ci 33fad3a1d3Sopenharmony_ci snapshot!(stmt, @r###" 34fad3a1d3Sopenharmony_ci Stmt::Local { 35fad3a1d3Sopenharmony_ci pat: Pat::Wild, 36fad3a1d3Sopenharmony_ci init: Some(LocalInit { 37fad3a1d3Sopenharmony_ci expr: Expr::Reference { 38fad3a1d3Sopenharmony_ci expr: Expr::Path { 39fad3a1d3Sopenharmony_ci path: Path { 40fad3a1d3Sopenharmony_ci segments: [ 41fad3a1d3Sopenharmony_ci PathSegment { 42fad3a1d3Sopenharmony_ci ident: "raw", 43fad3a1d3Sopenharmony_ci }, 44fad3a1d3Sopenharmony_ci ], 45fad3a1d3Sopenharmony_ci }, 46fad3a1d3Sopenharmony_ci }, 47fad3a1d3Sopenharmony_ci }, 48fad3a1d3Sopenharmony_ci }), 49fad3a1d3Sopenharmony_ci } 50fad3a1d3Sopenharmony_ci "###); 51fad3a1d3Sopenharmony_ci} 52fad3a1d3Sopenharmony_ci 53fad3a1d3Sopenharmony_ci#[test] 54fad3a1d3Sopenharmony_cifn test_raw_invalid() { 55fad3a1d3Sopenharmony_ci assert!(syn::parse_str::<Stmt>("let _ = &raw x;").is_err()); 56fad3a1d3Sopenharmony_ci} 57fad3a1d3Sopenharmony_ci 58fad3a1d3Sopenharmony_ci#[test] 59fad3a1d3Sopenharmony_cifn test_none_group() { 60fad3a1d3Sopenharmony_ci // <Ø async fn f() {} Ø> 61fad3a1d3Sopenharmony_ci let tokens = TokenStream::from_iter(vec![TokenTree::Group(Group::new( 62fad3a1d3Sopenharmony_ci Delimiter::None, 63fad3a1d3Sopenharmony_ci TokenStream::from_iter(vec![ 64fad3a1d3Sopenharmony_ci TokenTree::Ident(Ident::new("async", Span::call_site())), 65fad3a1d3Sopenharmony_ci TokenTree::Ident(Ident::new("fn", Span::call_site())), 66fad3a1d3Sopenharmony_ci TokenTree::Ident(Ident::new("f", Span::call_site())), 67fad3a1d3Sopenharmony_ci TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())), 68fad3a1d3Sopenharmony_ci TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())), 69fad3a1d3Sopenharmony_ci ]), 70fad3a1d3Sopenharmony_ci ))]); 71fad3a1d3Sopenharmony_ci snapshot!(tokens as Stmt, @r###" 72fad3a1d3Sopenharmony_ci Stmt::Item(Item::Fn { 73fad3a1d3Sopenharmony_ci vis: Visibility::Inherited, 74fad3a1d3Sopenharmony_ci sig: Signature { 75fad3a1d3Sopenharmony_ci asyncness: Some, 76fad3a1d3Sopenharmony_ci ident: "f", 77fad3a1d3Sopenharmony_ci generics: Generics, 78fad3a1d3Sopenharmony_ci output: ReturnType::Default, 79fad3a1d3Sopenharmony_ci }, 80fad3a1d3Sopenharmony_ci block: Block { 81fad3a1d3Sopenharmony_ci stmts: [], 82fad3a1d3Sopenharmony_ci }, 83fad3a1d3Sopenharmony_ci }) 84fad3a1d3Sopenharmony_ci "###); 85fad3a1d3Sopenharmony_ci 86fad3a1d3Sopenharmony_ci let tokens = Group::new(Delimiter::None, quote!(let None = None)).to_token_stream(); 87fad3a1d3Sopenharmony_ci let stmts = Block::parse_within.parse2(tokens).unwrap(); 88fad3a1d3Sopenharmony_ci snapshot!(stmts, @r###" 89fad3a1d3Sopenharmony_ci [ 90fad3a1d3Sopenharmony_ci Stmt::Expr( 91fad3a1d3Sopenharmony_ci Expr::Group { 92fad3a1d3Sopenharmony_ci expr: Expr::Let { 93fad3a1d3Sopenharmony_ci pat: Pat::Ident { 94fad3a1d3Sopenharmony_ci ident: "None", 95fad3a1d3Sopenharmony_ci }, 96fad3a1d3Sopenharmony_ci expr: Expr::Path { 97fad3a1d3Sopenharmony_ci path: Path { 98fad3a1d3Sopenharmony_ci segments: [ 99fad3a1d3Sopenharmony_ci PathSegment { 100fad3a1d3Sopenharmony_ci ident: "None", 101fad3a1d3Sopenharmony_ci }, 102fad3a1d3Sopenharmony_ci ], 103fad3a1d3Sopenharmony_ci }, 104fad3a1d3Sopenharmony_ci }, 105fad3a1d3Sopenharmony_ci }, 106fad3a1d3Sopenharmony_ci }, 107fad3a1d3Sopenharmony_ci None, 108fad3a1d3Sopenharmony_ci ), 109fad3a1d3Sopenharmony_ci ] 110fad3a1d3Sopenharmony_ci "###); 111fad3a1d3Sopenharmony_ci} 112fad3a1d3Sopenharmony_ci 113fad3a1d3Sopenharmony_ci#[test] 114fad3a1d3Sopenharmony_cifn test_let_dot_dot() { 115fad3a1d3Sopenharmony_ci let tokens = quote! { 116fad3a1d3Sopenharmony_ci let .. = 10; 117fad3a1d3Sopenharmony_ci }; 118fad3a1d3Sopenharmony_ci 119fad3a1d3Sopenharmony_ci snapshot!(tokens as Stmt, @r###" 120fad3a1d3Sopenharmony_ci Stmt::Local { 121fad3a1d3Sopenharmony_ci pat: Pat::Rest, 122fad3a1d3Sopenharmony_ci init: Some(LocalInit { 123fad3a1d3Sopenharmony_ci expr: Expr::Lit { 124fad3a1d3Sopenharmony_ci lit: 10, 125fad3a1d3Sopenharmony_ci }, 126fad3a1d3Sopenharmony_ci }), 127fad3a1d3Sopenharmony_ci } 128fad3a1d3Sopenharmony_ci "###); 129fad3a1d3Sopenharmony_ci} 130fad3a1d3Sopenharmony_ci 131fad3a1d3Sopenharmony_ci#[test] 132fad3a1d3Sopenharmony_cifn test_let_else() { 133fad3a1d3Sopenharmony_ci let tokens = quote! { 134fad3a1d3Sopenharmony_ci let Some(x) = None else { return 0; }; 135fad3a1d3Sopenharmony_ci }; 136fad3a1d3Sopenharmony_ci 137fad3a1d3Sopenharmony_ci snapshot!(tokens as Stmt, @r###" 138fad3a1d3Sopenharmony_ci Stmt::Local { 139fad3a1d3Sopenharmony_ci pat: Pat::TupleStruct { 140fad3a1d3Sopenharmony_ci path: Path { 141fad3a1d3Sopenharmony_ci segments: [ 142fad3a1d3Sopenharmony_ci PathSegment { 143fad3a1d3Sopenharmony_ci ident: "Some", 144fad3a1d3Sopenharmony_ci }, 145fad3a1d3Sopenharmony_ci ], 146fad3a1d3Sopenharmony_ci }, 147fad3a1d3Sopenharmony_ci elems: [ 148fad3a1d3Sopenharmony_ci Pat::Ident { 149fad3a1d3Sopenharmony_ci ident: "x", 150fad3a1d3Sopenharmony_ci }, 151fad3a1d3Sopenharmony_ci ], 152fad3a1d3Sopenharmony_ci }, 153fad3a1d3Sopenharmony_ci init: Some(LocalInit { 154fad3a1d3Sopenharmony_ci expr: Expr::Path { 155fad3a1d3Sopenharmony_ci path: Path { 156fad3a1d3Sopenharmony_ci segments: [ 157fad3a1d3Sopenharmony_ci PathSegment { 158fad3a1d3Sopenharmony_ci ident: "None", 159fad3a1d3Sopenharmony_ci }, 160fad3a1d3Sopenharmony_ci ], 161fad3a1d3Sopenharmony_ci }, 162fad3a1d3Sopenharmony_ci }, 163fad3a1d3Sopenharmony_ci diverge: Some(Expr::Block { 164fad3a1d3Sopenharmony_ci block: Block { 165fad3a1d3Sopenharmony_ci stmts: [ 166fad3a1d3Sopenharmony_ci Stmt::Expr( 167fad3a1d3Sopenharmony_ci Expr::Return { 168fad3a1d3Sopenharmony_ci expr: Some(Expr::Lit { 169fad3a1d3Sopenharmony_ci lit: 0, 170fad3a1d3Sopenharmony_ci }), 171fad3a1d3Sopenharmony_ci }, 172fad3a1d3Sopenharmony_ci Some, 173fad3a1d3Sopenharmony_ci ), 174fad3a1d3Sopenharmony_ci ], 175fad3a1d3Sopenharmony_ci }, 176fad3a1d3Sopenharmony_ci }), 177fad3a1d3Sopenharmony_ci }), 178fad3a1d3Sopenharmony_ci } 179fad3a1d3Sopenharmony_ci "###); 180fad3a1d3Sopenharmony_ci} 181fad3a1d3Sopenharmony_ci 182fad3a1d3Sopenharmony_ci#[test] 183fad3a1d3Sopenharmony_cifn test_macros() { 184fad3a1d3Sopenharmony_ci let tokens = quote! { 185fad3a1d3Sopenharmony_ci fn main() { 186fad3a1d3Sopenharmony_ci macro_rules! mac {} 187fad3a1d3Sopenharmony_ci thread_local! { static FOO } 188fad3a1d3Sopenharmony_ci println!(""); 189fad3a1d3Sopenharmony_ci vec![] 190fad3a1d3Sopenharmony_ci } 191fad3a1d3Sopenharmony_ci }; 192fad3a1d3Sopenharmony_ci 193fad3a1d3Sopenharmony_ci snapshot!(tokens as Stmt, @r###" 194fad3a1d3Sopenharmony_ci Stmt::Item(Item::Fn { 195fad3a1d3Sopenharmony_ci vis: Visibility::Inherited, 196fad3a1d3Sopenharmony_ci sig: Signature { 197fad3a1d3Sopenharmony_ci ident: "main", 198fad3a1d3Sopenharmony_ci generics: Generics, 199fad3a1d3Sopenharmony_ci output: ReturnType::Default, 200fad3a1d3Sopenharmony_ci }, 201fad3a1d3Sopenharmony_ci block: Block { 202fad3a1d3Sopenharmony_ci stmts: [ 203fad3a1d3Sopenharmony_ci Stmt::Item(Item::Macro { 204fad3a1d3Sopenharmony_ci ident: Some("mac"), 205fad3a1d3Sopenharmony_ci mac: Macro { 206fad3a1d3Sopenharmony_ci path: Path { 207fad3a1d3Sopenharmony_ci segments: [ 208fad3a1d3Sopenharmony_ci PathSegment { 209fad3a1d3Sopenharmony_ci ident: "macro_rules", 210fad3a1d3Sopenharmony_ci }, 211fad3a1d3Sopenharmony_ci ], 212fad3a1d3Sopenharmony_ci }, 213fad3a1d3Sopenharmony_ci delimiter: MacroDelimiter::Brace, 214fad3a1d3Sopenharmony_ci tokens: TokenStream(``), 215fad3a1d3Sopenharmony_ci }, 216fad3a1d3Sopenharmony_ci }), 217fad3a1d3Sopenharmony_ci Stmt::Macro { 218fad3a1d3Sopenharmony_ci mac: Macro { 219fad3a1d3Sopenharmony_ci path: Path { 220fad3a1d3Sopenharmony_ci segments: [ 221fad3a1d3Sopenharmony_ci PathSegment { 222fad3a1d3Sopenharmony_ci ident: "thread_local", 223fad3a1d3Sopenharmony_ci }, 224fad3a1d3Sopenharmony_ci ], 225fad3a1d3Sopenharmony_ci }, 226fad3a1d3Sopenharmony_ci delimiter: MacroDelimiter::Brace, 227fad3a1d3Sopenharmony_ci tokens: TokenStream(`static FOO`), 228fad3a1d3Sopenharmony_ci }, 229fad3a1d3Sopenharmony_ci }, 230fad3a1d3Sopenharmony_ci Stmt::Macro { 231fad3a1d3Sopenharmony_ci mac: Macro { 232fad3a1d3Sopenharmony_ci path: Path { 233fad3a1d3Sopenharmony_ci segments: [ 234fad3a1d3Sopenharmony_ci PathSegment { 235fad3a1d3Sopenharmony_ci ident: "println", 236fad3a1d3Sopenharmony_ci }, 237fad3a1d3Sopenharmony_ci ], 238fad3a1d3Sopenharmony_ci }, 239fad3a1d3Sopenharmony_ci delimiter: MacroDelimiter::Paren, 240fad3a1d3Sopenharmony_ci tokens: TokenStream(`""`), 241fad3a1d3Sopenharmony_ci }, 242fad3a1d3Sopenharmony_ci semi_token: Some, 243fad3a1d3Sopenharmony_ci }, 244fad3a1d3Sopenharmony_ci Stmt::Expr( 245fad3a1d3Sopenharmony_ci Expr::Macro { 246fad3a1d3Sopenharmony_ci mac: Macro { 247fad3a1d3Sopenharmony_ci path: Path { 248fad3a1d3Sopenharmony_ci segments: [ 249fad3a1d3Sopenharmony_ci PathSegment { 250fad3a1d3Sopenharmony_ci ident: "vec", 251fad3a1d3Sopenharmony_ci }, 252fad3a1d3Sopenharmony_ci ], 253fad3a1d3Sopenharmony_ci }, 254fad3a1d3Sopenharmony_ci delimiter: MacroDelimiter::Bracket, 255fad3a1d3Sopenharmony_ci tokens: TokenStream(``), 256fad3a1d3Sopenharmony_ci }, 257fad3a1d3Sopenharmony_ci }, 258fad3a1d3Sopenharmony_ci None, 259fad3a1d3Sopenharmony_ci ), 260fad3a1d3Sopenharmony_ci ], 261fad3a1d3Sopenharmony_ci }, 262fad3a1d3Sopenharmony_ci }) 263fad3a1d3Sopenharmony_ci "###); 264fad3a1d3Sopenharmony_ci} 265fad3a1d3Sopenharmony_ci 266fad3a1d3Sopenharmony_ci#[test] 267fad3a1d3Sopenharmony_cifn test_early_parse_loop() { 268fad3a1d3Sopenharmony_ci // The following is an Expr::Loop followed by Expr::Tuple. It is not an 269fad3a1d3Sopenharmony_ci // Expr::Call. 270fad3a1d3Sopenharmony_ci let tokens = quote! { 271fad3a1d3Sopenharmony_ci loop {} 272fad3a1d3Sopenharmony_ci () 273fad3a1d3Sopenharmony_ci }; 274fad3a1d3Sopenharmony_ci 275fad3a1d3Sopenharmony_ci let stmts = Block::parse_within.parse2(tokens).unwrap(); 276fad3a1d3Sopenharmony_ci 277fad3a1d3Sopenharmony_ci snapshot!(stmts, @r###" 278fad3a1d3Sopenharmony_ci [ 279fad3a1d3Sopenharmony_ci Stmt::Expr( 280fad3a1d3Sopenharmony_ci Expr::Loop { 281fad3a1d3Sopenharmony_ci body: Block { 282fad3a1d3Sopenharmony_ci stmts: [], 283fad3a1d3Sopenharmony_ci }, 284fad3a1d3Sopenharmony_ci }, 285fad3a1d3Sopenharmony_ci None, 286fad3a1d3Sopenharmony_ci ), 287fad3a1d3Sopenharmony_ci Stmt::Expr( 288fad3a1d3Sopenharmony_ci Expr::Tuple, 289fad3a1d3Sopenharmony_ci None, 290fad3a1d3Sopenharmony_ci ), 291fad3a1d3Sopenharmony_ci ] 292fad3a1d3Sopenharmony_ci "###); 293fad3a1d3Sopenharmony_ci 294fad3a1d3Sopenharmony_ci let tokens = quote! { 295fad3a1d3Sopenharmony_ci 'a: loop {} 296fad3a1d3Sopenharmony_ci () 297fad3a1d3Sopenharmony_ci }; 298fad3a1d3Sopenharmony_ci 299fad3a1d3Sopenharmony_ci let stmts = Block::parse_within.parse2(tokens).unwrap(); 300fad3a1d3Sopenharmony_ci 301fad3a1d3Sopenharmony_ci snapshot!(stmts, @r###" 302fad3a1d3Sopenharmony_ci [ 303fad3a1d3Sopenharmony_ci Stmt::Expr( 304fad3a1d3Sopenharmony_ci Expr::Loop { 305fad3a1d3Sopenharmony_ci label: Some(Label { 306fad3a1d3Sopenharmony_ci name: Lifetime { 307fad3a1d3Sopenharmony_ci ident: "a", 308fad3a1d3Sopenharmony_ci }, 309fad3a1d3Sopenharmony_ci }), 310fad3a1d3Sopenharmony_ci body: Block { 311fad3a1d3Sopenharmony_ci stmts: [], 312fad3a1d3Sopenharmony_ci }, 313fad3a1d3Sopenharmony_ci }, 314fad3a1d3Sopenharmony_ci None, 315fad3a1d3Sopenharmony_ci ), 316fad3a1d3Sopenharmony_ci Stmt::Expr( 317fad3a1d3Sopenharmony_ci Expr::Tuple, 318fad3a1d3Sopenharmony_ci None, 319fad3a1d3Sopenharmony_ci ), 320fad3a1d3Sopenharmony_ci ] 321fad3a1d3Sopenharmony_ci "###); 322fad3a1d3Sopenharmony_ci} 323