3 use rustc_ast::token::{self, Token};
4 use rustc_ast::tokenstream::{TokenStream, TokenTree};
5 use rustc_expand::base::{self, *};
6 use rustc_span::symbol::{Ident, Symbol};
9 pub fn expand_concat_idents<'cx>(
10 cx: &'cx mut ExtCtxt<'_>,
13 ) -> Box<dyn base::MacResult + 'cx> {
15 cx.span_err(sp, "concat_idents! takes 1 or more arguments");
16 return DummyResult::any(sp);
19 let mut res_str = String::new();
20 for (i, e) in tts.into_trees().enumerate() {
23 TokenTree::Token(Token { kind: token::Comma, .. }, _) => {}
25 cx.span_err(sp, "concat_idents! expecting comma");
26 return DummyResult::any(sp);
30 if let TokenTree::Token(token, _) = e {
31 if let Some((ident, _)) = token.ident() {
32 res_str.push_str(ident.name.as_str());
37 cx.span_err(sp, "concat_idents! requires ident args");
38 return DummyResult::any(sp);
42 let ident = Ident::new(Symbol::intern(&res_str), cx.with_call_site_ctxt(sp));
44 struct ConcatIdentsResult {
48 impl base::MacResult for ConcatIdentsResult {
49 fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
51 id: ast::DUMMY_NODE_ID,
52 kind: ast::ExprKind::Path(None, ast::Path::from_ident(self.ident)),
53 span: self.ident.span,
54 attrs: ast::AttrVec::new(),
59 fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
61 id: ast::DUMMY_NODE_ID,
62 kind: ast::TyKind::Path(None, ast::Path::from_ident(self.ident)),
63 span: self.ident.span,
69 Box::new(ConcatIdentsResult { ident })