Skip to content

Commit 477c1ac

Browse files
bors[bot]vlad20012
andauthored
Merge #7827
7827: Fix proc macro TokenStream::from_str token ids r=vlad20012 a=vlad20012 To be honest, I don't know what it changes from a user perspective. Internally, this fixes spans (token ids) of a `TokenStream` parsed from a string: ```rust #[proc_macro_derive(FooDerive)] pub fn foo_derive(item: TokenStream) -> TokenStream { "fn foo() {}".parse().unwrap() } ``` Previously, `TokenStream` was constructed from tokens with incremental ids (that conflicted with call-site tokens). Now they are `-1`. Co-authored-by: vlad20012 <[email protected]>
2 parents 10a57b8 + a157f19 commit 477c1ac

File tree

1 file changed

+38
-2
lines changed

1 file changed

+38
-2
lines changed

crates/proc_macro_srv/src/rustc_server.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use std::collections::HashMap;
1414
use std::hash::Hash;
1515
use std::iter::FromIterator;
1616
use std::ops::Bound;
17-
use std::str::FromStr;
1817
use std::{ascii, vec::IntoIter};
1918

2019
type Group = tt::Subtree;
@@ -278,6 +277,42 @@ impl server::FreeFunctions for Rustc {
278277
}
279278
}
280279

280+
fn subtree_replace_token_ids_with_unspecified(subtree: tt::Subtree) -> tt::Subtree {
281+
tt::Subtree {
282+
delimiter: subtree.delimiter.map(|d| tt::Delimiter { id: tt::TokenId::unspecified(), ..d }),
283+
token_trees: subtree
284+
.token_trees
285+
.into_iter()
286+
.map(|t| token_tree_replace_token_ids_with_unspecified(t))
287+
.collect(),
288+
}
289+
}
290+
291+
fn token_tree_replace_token_ids_with_unspecified(tt: tt::TokenTree) -> tt::TokenTree {
292+
match tt {
293+
tt::TokenTree::Leaf(leaf) => {
294+
tt::TokenTree::Leaf(leaf_replace_token_ids_with_unspecified(leaf))
295+
}
296+
tt::TokenTree::Subtree(subtree) => {
297+
tt::TokenTree::Subtree(subtree_replace_token_ids_with_unspecified(subtree))
298+
}
299+
}
300+
}
301+
302+
fn leaf_replace_token_ids_with_unspecified(leaf: tt::Leaf) -> tt::Leaf {
303+
match leaf {
304+
tt::Leaf::Literal(lit) => {
305+
tt::Leaf::Literal(tt::Literal { id: tt::TokenId::unspecified(), ..lit })
306+
}
307+
tt::Leaf::Punct(punct) => {
308+
tt::Leaf::Punct(tt::Punct { id: tt::TokenId::unspecified(), ..punct })
309+
}
310+
tt::Leaf::Ident(ident) => {
311+
tt::Leaf::Ident(tt::Ident { id: tt::TokenId::unspecified(), ..ident })
312+
}
313+
}
314+
}
315+
281316
impl server::TokenStream for Rustc {
282317
fn new(&mut self) -> Self::TokenStream {
283318
Self::TokenStream::new()
@@ -287,7 +322,8 @@ impl server::TokenStream for Rustc {
287322
stream.is_empty()
288323
}
289324
fn from_str(&mut self, src: &str) -> Self::TokenStream {
290-
Self::TokenStream::from_str(src).expect("cannot parse string")
325+
let (subtree, _) = mbe::parse_to_token_tree(src).expect("cannot parse string");
326+
TokenStream::with_subtree(subtree_replace_token_ids_with_unspecified(subtree))
291327
}
292328
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
293329
stream.to_string()

0 commit comments

Comments
 (0)