From bbc151ef323be4c467bba9ea7699852adfea15e1 Mon Sep 17 00:00:00 2001
From: Edwin Cheng <edwin0cheng@gmail.com>
Date: Fri, 14 May 2021 06:42:10 +0800
Subject: Implement `concat_idents`

---
 crates/hir_expand/src/builtin_macro.rs | 35 ++++++++++++++++++++++++++++++++++
 crates/hir_expand/src/name.rs          |  1 +
 2 files changed, 36 insertions(+)

(limited to 'crates/hir_expand')

diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index af9802144..280c25f11 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -118,6 +118,7 @@ register_builtin! {
     EAGER:
     (compile_error, CompileError) => compile_error_expand,
     (concat, Concat) => concat_expand,
+    (concat_idents, ConcatIdents) => concat_idents_expand,
     (include, Include) => include_expand,
     (include_bytes, IncludeBytes) => include_bytes_expand,
     (include_str, IncludeStr) => include_str_expand,
@@ -373,6 +374,28 @@ fn concat_expand(
     ExpandResult { value: Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)), err }
 }
 
+fn concat_idents_expand(
+    _db: &dyn AstDatabase,
+    _arg_id: EagerMacroId,
+    tt: &tt::Subtree,
+) -> ExpandResult<Option<ExpandedEager>> {
+    let mut err = None;
+    let mut ident = String::new();
+    for (i, t) in tt.token_trees.iter().enumerate() {
+        match t {
+            tt::TokenTree::Leaf(tt::Leaf::Ident(id)) => {
+                ident.push_str(id.text.as_str());
+            }
+            tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if i % 2 == 1 && punct.char == ',' => (),
+            _ => {
+                err.get_or_insert(mbe::ExpandError::UnexpectedToken);
+            }
+        }
+    }
+    let ident = tt::Ident { text: ident.into(), id: tt::TokenId::unspecified() };
+    ExpandResult { value: Some(ExpandedEager::new(quote!(#ident), FragmentKind::Expr)), err }
+}
+
 fn relative_file(
     db: &dyn AstDatabase,
     call_id: MacroCallId,
@@ -794,4 +817,16 @@ mod tests {
             expect![[r#""foor0bar\nfalse""#]],
         );
     }
+
+    #[test]
+    fn test_concat_idents_expand() {
+        check_expansion(
+            r##"
+            #[rustc_builtin_macro]
+            macro_rules! concat_idents {}
+            concat_idents!(foo, bar);
+            "##,
+            expect![[r#"foobar"#]],
+        );
+    }
 }
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index bcfd3e524..5a5dc9afd 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -212,6 +212,7 @@ pub mod known {
         std_panic,
         stringify,
         concat,
+        concat_idents,
         include,
         include_bytes,
         include_str,
-- 
cgit v1.2.3