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