aboutsummaryrefslogtreecommitdiff
path: root/crates/proc_macro_srv
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-03-02 00:01:14 +0000
committerGitHub <[email protected]>2021-03-02 00:01:14 +0000
commit477c1ac105a3b2ed8aafc8c3b09da81984725461 (patch)
treeb6fc2472e099bcd7237b2d6f8d79b1484112d7c4 /crates/proc_macro_srv
parent10a57b8109cbc54c6f6aaae3b61a56fd0529a24a (diff)
parenta157f19bf5bcfe6d59a754a0cb28ece30c526848 (diff)
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]>
Diffstat (limited to 'crates/proc_macro_srv')
-rw-r--r--crates/proc_macro_srv/src/rustc_server.rs40
1 files changed, 38 insertions, 2 deletions
diff --git a/crates/proc_macro_srv/src/rustc_server.rs b/crates/proc_macro_srv/src/rustc_server.rs
index a8504f762..952b4a97f 100644
--- a/crates/proc_macro_srv/src/rustc_server.rs
+++ b/crates/proc_macro_srv/src/rustc_server.rs
@@ -14,7 +14,6 @@ use std::collections::HashMap;
14use std::hash::Hash; 14use std::hash::Hash;
15use std::iter::FromIterator; 15use std::iter::FromIterator;
16use std::ops::Bound; 16use std::ops::Bound;
17use std::str::FromStr;
18use std::{ascii, vec::IntoIter}; 17use std::{ascii, vec::IntoIter};
19 18
20type Group = tt::Subtree; 19type Group = tt::Subtree;
@@ -278,6 +277,42 @@ impl server::FreeFunctions for Rustc {
278 } 277 }
279} 278}
280 279
280fn 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
291fn 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
302fn 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
281impl server::TokenStream for Rustc { 316impl server::TokenStream for Rustc {
282 fn new(&mut self) -> Self::TokenStream { 317 fn new(&mut self) -> Self::TokenStream {
283 Self::TokenStream::new() 318 Self::TokenStream::new()
@@ -287,7 +322,8 @@ impl server::TokenStream for Rustc {
287 stream.is_empty() 322 stream.is_empty()
288 } 323 }
289 fn from_str(&mut self, src: &str) -> Self::TokenStream { 324 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))
291 } 327 }
292 fn to_string(&mut self, stream: &Self::TokenStream) -> String { 328 fn to_string(&mut self, stream: &Self::TokenStream) -> String {
293 stream.to_string() 329 stream.to_string()