diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-03-02 00:01:14 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-03-02 00:01:14 +0000 |
commit | 477c1ac105a3b2ed8aafc8c3b09da81984725461 (patch) | |
tree | b6fc2472e099bcd7237b2d6f8d79b1484112d7c4 /crates/proc_macro_srv | |
parent | 10a57b8109cbc54c6f6aaae3b61a56fd0529a24a (diff) | |
parent | a157f19bf5bcfe6d59a754a0cb28ece30c526848 (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.rs | 40 |
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; | |||
14 | use std::hash::Hash; | 14 | use std::hash::Hash; |
15 | use std::iter::FromIterator; | 15 | use std::iter::FromIterator; |
16 | use std::ops::Bound; | 16 | use std::ops::Bound; |
17 | use std::str::FromStr; | ||
18 | use std::{ascii, vec::IntoIter}; | 17 | use std::{ascii, vec::IntoIter}; |
19 | 18 | ||
20 | type Group = tt::Subtree; | 19 | type Group = tt::Subtree; |
@@ -278,6 +277,42 @@ impl server::FreeFunctions for Rustc { | |||
278 | } | 277 | } |
279 | } | 278 | } |
280 | 279 | ||
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 | |||
281 | impl server::TokenStream for Rustc { | 316 | impl 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() |