• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![allow(clippy::non_ascii_literal)]
2 
3 use proc_macro2::{Delimiter, Group, Punct, Spacing, TokenStream, TokenTree};
4 use syn::parse::{discouraged::Speculative, Parse, ParseStream, Parser, Result};
5 use syn::{parenthesized, Token};
6 
7 #[test]
8 #[should_panic(expected = "Fork was not derived from the advancing parse stream")]
smuggled_speculative_cursor_between_sources()9 fn 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")]
smuggled_speculative_cursor_between_brackets()26 fn 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")]
smuggled_speculative_cursor_into_brackets()44 fn 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]
trailing_empty_none_group()59 fn 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