Clone entire `TokenCursor` when collecting tokens

Reverts PR #80830
Fixes taiki-e/pin-project#312

We can have an arbitrary number of `None`-delimited group frames pushed
on the stack due to proc-macro invocations, which can legally be exited.
Attempting to account for this would add a lot of complexity for a tiny
performance gain, so let's just use the original strategy.
This commit is contained in:
Aaron Hill 2021-01-28 09:47:59 -05:00
parent 0e190206e2
commit 5d739180cd
No known key found for this signature in database
GPG Key ID: B4087E510E98B164
3 changed files with 41 additions and 9 deletions

View File

@ -1254,15 +1254,7 @@ impl<'a> Parser<'a> {
f: impl FnOnce(&mut Self) -> PResult<'a, (R, TrailingToken)>,
) -> PResult<'a, R> {
let start_token = (self.token.clone(), self.token_spacing);
let cursor_snapshot = TokenCursor {
frame: self.token_cursor.frame.clone(),
// We only ever capture tokens within our current frame,
// so we can just use an empty frame stack
stack: vec![],
desugar_doc_comments: self.token_cursor.desugar_doc_comments,
num_next_calls: self.token_cursor.num_next_calls,
append_unglued_token: self.token_cursor.append_unglued_token.clone(),
};
let cursor_snapshot = self.token_cursor.clone();
let (mut ret, trailing_token) = f(self)?;

View File

@ -0,0 +1,23 @@
// force-host
// no-prefer-dynamic
#![crate_type = "proc-macro"]
#![feature(proc_macro_quote)]
extern crate proc_macro;
use proc_macro::{TokenStream, quote};
#[proc_macro_attribute]
pub fn first_attr(_: TokenStream, input: TokenStream) -> TokenStream {
let recollected: TokenStream = input.into_iter().collect();
quote! {
#[second_attr]
$recollected
}
}
#[proc_macro_attribute]
pub fn second_attr(_: TokenStream, input: TokenStream) -> TokenStream {
let _recollected: TokenStream = input.into_iter().collect();
TokenStream::new()
}

View File

@ -0,0 +1,17 @@
// check-pass
// aux-build:nonterminal-recollect-attr.rs
extern crate nonterminal_recollect_attr;
use nonterminal_recollect_attr::*;
macro_rules! my_macro {
($v:ident) => {
#[first_attr]
$v struct Foo {
field: u8
}
}
}
my_macro!(pub);
fn main() {}