1#![allow(clippy::non_ascii_literal)] 2 3use proc_macro2::{Delimiter, Group, Punct, Spacing, TokenStream, TokenTree}; 4use syn::parse::discouraged::Speculative as _; 5use syn::parse::{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