From 915ca09e505faa720739782de318b5c9b2914ec0 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 10 Oct 2020 15:48:27 -0700 Subject: [PATCH 1/2] Add regression test of pattern inside None group --- tests/test_pat.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/test_pat.rs b/tests/test_pat.rs index 73388dd79d..399de0289d 100644 --- a/tests/test_pat.rs +++ b/tests/test_pat.rs @@ -1,4 +1,9 @@ +#[macro_use] +mod macros; + +use proc_macro2::{Delimiter, Group, TokenStream, TokenTree}; use quote::quote; +use std::iter::FromIterator; use syn::{Item, Pat, Stmt}; #[test] @@ -36,3 +41,27 @@ fn test_leading_vert() { syn::parse_str::("let NS { f: | A }: NS;").unwrap_err(); syn::parse_str::("let NS { f: || A }: NS;").unwrap_err(); } + +#[test] +fn test_group() { + let group = Group::new(Delimiter::None, quote!(Some(_))); + let tokens = TokenStream::from_iter(vec![TokenTree::Group(group)]); + + snapshot!(tokens as Pat, @r###" + Pat::TupleStruct { + path: Path { + segments: [ + PathSegment { + ident: "Some", + arguments: None, + }, + ], + }, + pat: PatTuple { + elems: [ + Pat::Wild, + ], + }, + } + "###); +} From 43cdc12a44cb581fa32246b90bf993a05de9bee9 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 10 Oct 2020 15:41:04 -0700 Subject: [PATCH 2/2] Fix parsing path Pat inside of None-delimited group --- src/pat.rs | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/pat.rs b/src/pat.rs index a856318a3b..473ee1c834 100644 --- a/src/pat.rs +++ b/src/pat.rs @@ -285,22 +285,20 @@ pub mod parsing { fn parse(input: ParseStream) -> Result { let begin = input.fork(); let lookahead = input.lookahead1(); - if lookahead.peek(Ident) - && ({ - input.peek2(Token![::]) - || input.peek2(Token![!]) - || input.peek2(token::Brace) - || input.peek2(token::Paren) - || input.peek2(Token![..]) - && !{ - let ahead = input.fork(); - ahead.parse::()?; - ahead.parse::()?; - ahead.is_empty() || ahead.peek(Token![,]) - } - }) - || input.peek(Token![self]) && input.peek2(Token![::]) - || lookahead.peek(Token![::]) + if { + let ahead = input.fork(); + ahead.parse::>()?.is_some() + && (ahead.peek(Token![::]) + || ahead.peek(Token![!]) + || ahead.peek(token::Brace) + || ahead.peek(token::Paren) + || ahead.peek(Token![..]) + && ahead.parse::().is_ok() + && !(ahead.is_empty() || ahead.peek(Token![,]))) + } || { + let ahead = input.fork(); + ahead.parse::>()?.is_some() && ahead.peek(Token![::]) + } || lookahead.peek(Token![::]) || lookahead.peek(Token![<]) || input.peek(Token![Self]) || input.peek(Token![super])