1#![allow(clippy::non_ascii_literal)]
2
3use proc_macro2::{Delimiter, Group, Punct, Spacing, TokenStream, TokenTree};
4use syn::parse::{discouraged::Speculative, Parse, ParseStream, Parser, Result};
5use syn::{parenthesized, Token};
6
7#[test]
8#[should_panic(expected = "Fork was not derived from the advancing parse stream")]
9fn smuggled_speculative_cursor_between_sources() {
10 struct BreakRules;
11 impl Parse for BreakRules {
12 fn parse(input1: ParseStream) -> Result<Self> {
13 let nested = |input2: ParseStream| {
14 input1.advance_to(input2);
15 Ok(Self)
16 };
17 nested.parse_str("")
18 }
19 }
20
21 syn::parse_str::<BreakRules>("").unwrap();
22}
23
24#[test]
25#[should_panic(expected = "Fork was not derived from the advancing parse stream")]
26fn smuggled_speculative_cursor_between_brackets() {
27 struct BreakRules;
28 impl Parse for BreakRules {
29 fn parse(input: ParseStream) -> Result<Self> {
30 let a;
31 let b;
32 parenthesized!(a in input);
33 parenthesized!(b in input);
34 a.advance_to(&b);
35 Ok(Self)
36 }
37 }
38
39 syn::parse_str::<BreakRules>("()()").unwrap();
40}
41
42#[test]
43#[should_panic(expected = "Fork was not derived from the advancing parse stream")]
44fn smuggled_speculative_cursor_into_brackets() {
45 struct BreakRules;
46 impl Parse for BreakRules {
47 fn parse(input: ParseStream) -> Result<Self> {
48 let a;
49 parenthesized!(a in input);
50 input.advance_to(&a);
51 Ok(Self)
52 }
53 }
54
55 syn::parse_str::<BreakRules>("()").unwrap();
56}
57
58#[test]
59fn trailing_empty_none_group() {
60 fn parse(input: ParseStream) -> Result<()> {
61 input.parse::<Token![+]>()?;
62
63 let content;
64 parenthesized!(content in input);
65 content.parse::<Token![+]>()?;
66
67 Ok(())
68 }
69
70 // `+ ( + <Ø Ø> ) <Ø <Ø Ø> Ø>`
71 let tokens = TokenStream::from_iter(vec![
72 TokenTree::Punct(Punct::new('+', Spacing::Alone)),
73 TokenTree::Group(Group::new(
74 Delimiter::Parenthesis,
75 TokenStream::from_iter(vec![
76 TokenTree::Punct(Punct::new('+', Spacing::Alone)),
77 TokenTree::Group(Group::new(Delimiter::None, TokenStream::new())),
78 ]),
79 )),
80 TokenTree::Group(Group::new(Delimiter::None, TokenStream::new())),
81 TokenTree::Group(Group::new(
82 Delimiter::None,
83 TokenStream::from_iter(vec![TokenTree::Group(Group::new(
84 Delimiter::None,
85 TokenStream::new(),
86 ))]),
87 )),
88 ]);
89
90 parse.parse2(tokens).unwrap();
91}
92