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