about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros/src/concat_idents.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_builtin_macros/src/concat_idents.rs')
-rw-r--r--compiler/rustc_builtin_macros/src/concat_idents.rs69
1 files changed, 69 insertions, 0 deletions
diff --git a/compiler/rustc_builtin_macros/src/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs
new file mode 100644
index 00000000000..8223cdda072
--- /dev/null
+++ b/compiler/rustc_builtin_macros/src/concat_idents.rs
@@ -0,0 +1,69 @@
+use rustc_ast as ast;
+use rustc_ast::ptr::P;
+use rustc_ast::token::{self, Token};
+use rustc_ast::tokenstream::{TokenStream, TokenTree};
+use rustc_expand::base::{self, *};
+use rustc_span::symbol::{Ident, Symbol};
+use rustc_span::Span;
+
+pub fn expand_concat_idents<'cx>(
+    cx: &'cx mut ExtCtxt<'_>,
+    sp: Span,
+    tts: TokenStream,
+) -> Box<dyn base::MacResult + 'cx> {
+    if tts.is_empty() {
+        cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
+        return DummyResult::any(sp);
+    }
+
+    let mut res_str = String::new();
+    for (i, e) in tts.into_trees().enumerate() {
+        if i & 1 == 1 {
+            match e {
+                TokenTree::Token(Token { kind: token::Comma, .. }) => {}
+                _ => {
+                    cx.span_err(sp, "concat_idents! expecting comma.");
+                    return DummyResult::any(sp);
+                }
+            }
+        } else {
+            match e {
+                TokenTree::Token(Token { kind: token::Ident(name, _), .. }) => {
+                    res_str.push_str(&name.as_str())
+                }
+                _ => {
+                    cx.span_err(sp, "concat_idents! requires ident args.");
+                    return DummyResult::any(sp);
+                }
+            }
+        }
+    }
+
+    let ident = Ident::new(Symbol::intern(&res_str), cx.with_call_site_ctxt(sp));
+
+    struct ConcatIdentsResult {
+        ident: Ident,
+    }
+
+    impl base::MacResult for ConcatIdentsResult {
+        fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
+            Some(P(ast::Expr {
+                id: ast::DUMMY_NODE_ID,
+                kind: ast::ExprKind::Path(None, ast::Path::from_ident(self.ident)),
+                span: self.ident.span,
+                attrs: ast::AttrVec::new(),
+                tokens: None,
+            }))
+        }
+
+        fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
+            Some(P(ast::Ty {
+                id: ast::DUMMY_NODE_ID,
+                kind: ast::TyKind::Path(None, ast::Path::from_ident(self.ident)),
+                span: self.ident.span,
+            }))
+        }
+    }
+
+    Box::new(ConcatIdentsResult { ident })
+}