Skip to content

Commit

Permalink
Fix bug in Parser::look_ahead.
Browse files Browse the repository at this point in the history
The special case was failing to handle invisible delimiters on one path.

Fixes rust-lang#128895.
  • Loading branch information
nnethercote committed Aug 12, 2024
1 parent fac7753 commit 46b4c5a
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 4 deletions.
10 changes: 6 additions & 4 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1166,10 +1166,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));
}
}
};
}
Expand Down
44 changes: 44 additions & 0 deletions tests/ui/proc-macro/auxiliary/parse-invis-delim-issue-128895.rs
Original file line number Diff line number Diff line change
@@ -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>()
}
14 changes: 14 additions & 0 deletions tests/ui/proc-macro/parse-invis-delim-issue-128895.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit 46b4c5a

Please sign in to comment.