about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-12-31 05:37:08 +0000
committerGitHub <noreply@github.com>2020-12-31 05:37:08 +0000
commita9814fa9c037b0fafd30580a6e7682ed032d77e6 (patch)
tree3279a35ba6f22e7cdf22757bc2ce646c44cb5aa2
parentbed7be9ed9f3eb905ae1c377f154fe0990b4c87f (diff)
parent1bd1830f507ee4ca63d65588e0eb8855bc825f23 (diff)
downloadrust-a9814fa9c037b0fafd30580a6e7682ed032d77e6.tar.gz
rust-a9814fa9c037b0fafd30580a6e7682ed032d77e6.zip
Merge #7101
7101: Fix spacing bug in proc-macro TokenStream::to_string r=edwin0cheng a=edwin0cheng

bors r+

fixes #7100

Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
-rw-r--r--crates/proc_macro_srv/src/rustc_server.rs43
1 files changed, 36 insertions, 7 deletions
diff --git a/crates/proc_macro_srv/src/rustc_server.rs b/crates/proc_macro_srv/src/rustc_server.rs
index 503f4c1014a..b54aa1f3bf1 100644
--- a/crates/proc_macro_srv/src/rustc_server.rs
+++ b/crates/proc_macro_srv/src/rustc_server.rs
@@ -204,17 +204,18 @@ pub mod token_stream {
                 let content = subtree
                     .token_trees
                     .iter()
-                    .map(|tkn| {
-                        let s = to_text(tkn);
+                    .fold((String::new(), true), |(last, last_to_joint), tkn| {
+                        let s = [last, to_text(tkn)].join(if last_to_joint { "" } else { " " });
+                        let mut is_joint = false;
                         if let tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) = tkn {
-                            if punct.spacing == tt::Spacing::Alone {
-                                return s + " ";
+                            if punct.spacing == tt::Spacing::Joint {
+                                is_joint = true;
                             }
                         }
-                        s
+                        (s, is_joint)
                     })
-                    .collect::<Vec<_>>()
-                    .concat();
+                    .0;
+
                 let (open, close) = match subtree.delimiter.map(|it| it.kind) {
                     None => ("", ""),
                     Some(tt::DelimiterKind::Brace) => ("{", "}"),
@@ -710,4 +711,32 @@ mod tests {
         assert_eq!(srv.character('c').text, "'c'");
         assert_eq!(srv.byte_string(b"1234586\x88").text, "b\"1234586\\x88\"");
     }
+
+    #[test]
+    fn test_rustc_server_to_string() {
+        let s = TokenStream {
+            subtree: tt::Subtree {
+                delimiter: None,
+                token_trees: vec![
+                    tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
+                        text: "struct".into(),
+                        id: tt::TokenId::unspecified(),
+                    })),
+                    tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
+                        text: "T".into(),
+                        id: tt::TokenId::unspecified(),
+                    })),
+                    tt::TokenTree::Subtree(tt::Subtree {
+                        delimiter: Some(tt::Delimiter {
+                            id: tt::TokenId::unspecified(),
+                            kind: tt::DelimiterKind::Brace,
+                        }),
+                        token_trees: vec![],
+                    }),
+                ],
+            },
+        };
+
+        assert_eq!(s.to_string(), "struct T {}");
+    }
 }