about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2024-08-12 17:09:20 +0200
committerGitHub <noreply@github.com>2024-08-12 17:09:20 +0200
commit99a785d62d8414e5db435f4e699eabd185257d49 (patch)
tree0dc7b9f6c09c2de39e702cb4751563c12b254835
parent7c6dca90509fe94e775bfd5d2c7132fb210f57b4 (diff)
parent46b4c5adc5698c3e9543e17a1ed0f8073bafd1d3 (diff)
downloadrust-99a785d62d8414e5db435f4e699eabd185257d49.tar.gz
rust-99a785d62d8414e5db435f4e699eabd185257d49.zip
Rollup merge of #128994 - nnethercote:fix-Parser-look_ahead-more, r=compiler-errors
Fix bug in `Parser::look_ahead`.

The special case was failing to handle invisible delimiters on one path.

Fixes (but doesn't close until beta backported) #128895.

r? `@davidtwco`
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs10
-rw-r--r--tests/ui/proc-macro/auxiliary/parse-invis-delim-issue-128895.rs44
-rw-r--r--tests/ui/proc-macro/parse-invis-delim-issue-128895.rs14
3 files changed, 64 insertions, 4 deletions
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index b7dc21bfc07..9b3b6d5f9ad 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1167,10 +1167,12 @@ impl<'a> Parser<'a> {
             match self.token_cursor.tree_cursor.look_ahead(0) {
                 Some(tree) => {
                     // Indexing stayed within the current token tree.
-                    return match tree {
-                        TokenTree::Token(token, _) => looker(token),
-                        TokenTree::Delimited(dspan, _, delim, _) => {
-                            looker(&Token::new(token::OpenDelim(*delim), dspan.open))
+                    match tree {
+                        TokenTree::Token(token, _) => return looker(token),
+                        &TokenTree::Delimited(dspan, _, delim, _) => {
+                            if delim != Delimiter::Invisible {
+                                return looker(&Token::new(token::OpenDelim(delim), dspan.open));
+                            }
                         }
                     };
                 }
diff --git a/tests/ui/proc-macro/auxiliary/parse-invis-delim-issue-128895.rs b/tests/ui/proc-macro/auxiliary/parse-invis-delim-issue-128895.rs
new file mode 100644
index 00000000000..07e135ee8eb
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/parse-invis-delim-issue-128895.rs
@@ -0,0 +1,44 @@
+//@ force-host
+//@ no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::*;
+
+// This proc macro ignores its input and returns this token stream
+//
+//   impl <«A1»: Comparable> Comparable for («A1»,) {}
+//
+// where `«`/`»` are invisible delimiters. This was being misparsed in bug
+// #128895.
+#[proc_macro]
+pub fn main(_input: TokenStream) -> TokenStream {
+    let a1 = TokenTree::Group(
+        Group::new(
+            Delimiter::None,
+            std::iter::once(TokenTree::Ident(Ident::new("A1", Span::call_site()))).collect(),
+        )
+    );
+    vec![
+        TokenTree::Ident(Ident::new("impl", Span::call_site())),
+        TokenTree::Punct(Punct::new('<', Spacing::Alone)),
+        a1.clone(),
+        TokenTree::Punct(Punct::new(':', Spacing::Alone)),
+        TokenTree::Ident(Ident::new("Comparable", Span::call_site())),
+        TokenTree::Punct(Punct::new('>', Spacing::Alone)),
+        TokenTree::Ident(Ident::new("Comparable", Span::call_site())),
+        TokenTree::Ident(Ident::new("for", Span::call_site())),
+        TokenTree::Group(
+            Group::new(
+                Delimiter::Parenthesis,
+                vec![
+                    a1.clone(),
+                    TokenTree::Punct(Punct::new(',', Spacing::Alone)),
+                ].into_iter().collect::<TokenStream>(),
+            )
+        ),
+        TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
+    ].into_iter().collect::<TokenStream>()
+}
diff --git a/tests/ui/proc-macro/parse-invis-delim-issue-128895.rs b/tests/ui/proc-macro/parse-invis-delim-issue-128895.rs
new file mode 100644
index 00000000000..3d5af5fee21
--- /dev/null
+++ b/tests/ui/proc-macro/parse-invis-delim-issue-128895.rs
@@ -0,0 +1,14 @@
+//@ aux-build:parse-invis-delim-issue-128895.rs
+//@ check-pass
+
+#![no_std] // Don't load unnecessary hygiene information from std
+extern crate std;
+
+#[macro_use]
+extern crate parse_invis_delim_issue_128895;
+
+trait Comparable {}
+
+parse_invis_delim_issue_128895::main!();
+
+fn main() {}