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