From eb7b1a150f4433241510610b25a6bca295514fb0 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 12 Apr 2021 11:15:38 -0400 Subject: [PATCH 1/2] Fix lookahead with None-delimited group --- compiler/rustc_parse/src/parser/mod.rs | 22 +++++++++++++--------- src/test/ui/macros/none-delim-lookahead.rs | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/macros/none-delim-lookahead.rs diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 4b97c8b0a81e1..0aa4fc4a13946 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -929,16 +929,20 @@ impl<'a> Parser<'a> { return looker(&self.token); } - let frame = &self.token_cursor.frame; - match frame.tree_cursor.look_ahead(dist - 1) { - Some(tree) => match tree { - TokenTree::Token(token) => looker(token), - TokenTree::Delimited(dspan, delim, _) => { - looker(&Token::new(token::OpenDelim(*delim), dspan.open)) - } - }, - None => looker(&Token::new(token::CloseDelim(frame.delim), frame.span.close)), + let mut cursor = self.token_cursor.clone(); + let mut i = 0; + let mut token = Token::dummy(); + while i < dist { + token = cursor.next().0; + if matches!( + token.kind, + token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) + ) { + continue; + } + i += 1; } + return looker(&token); } /// Returns whether any of the given keywords are `dist` tokens ahead of the current one. diff --git a/src/test/ui/macros/none-delim-lookahead.rs b/src/test/ui/macros/none-delim-lookahead.rs new file mode 100644 index 0000000000000..bf4fddea14ba2 --- /dev/null +++ b/src/test/ui/macros/none-delim-lookahead.rs @@ -0,0 +1,15 @@ +// check-pass + +macro_rules! make_struct { + ($name:ident) => { + #[derive(Debug)] + struct Foo { + #[cfg(not(FALSE))] + field: fn($name: bool) + } + } +} + +make_struct!(param_name); + +fn main() {} From c6d67f83170adf586abc93adedc8048e325611e1 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 12 Apr 2021 17:26:26 -0400 Subject: [PATCH 2/2] Add fast path when None delimiters are not involved --- compiler/rustc_parse/src/parser/mod.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 0aa4fc4a13946..ed95a5661b18e 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -929,6 +929,25 @@ impl<'a> Parser<'a> { return looker(&self.token); } + let frame = &self.token_cursor.frame; + if frame.delim != DelimToken::NoDelim { + let all_normal = (0..dist).all(|i| { + let token = frame.tree_cursor.look_ahead(i); + !matches!(token, Some(TokenTree::Delimited(_, DelimToken::NoDelim, _))) + }); + if all_normal { + return match frame.tree_cursor.look_ahead(dist - 1) { + Some(tree) => match tree { + TokenTree::Token(token) => looker(token), + TokenTree::Delimited(dspan, delim, _) => { + looker(&Token::new(token::OpenDelim(*delim), dspan.open)) + } + }, + None => looker(&Token::new(token::CloseDelim(frame.delim), frame.span.close)), + }; + } + } + let mut cursor = self.token_cursor.clone(); let mut i = 0; let mut token = Token::dummy();