1 use rustc_data_structures::thin_vec::ThinVec;
4 use syntax::ext::base::{self, *};
5 use syntax::feature_gate;
6 use syntax::parse::token;
9 use syntax_pos::symbol::{Symbol, sym};
10 use syntax::tokenstream::TokenTree;
12 pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
15 -> Box<dyn base::MacResult + 'cx> {
16 if !cx.ecfg.enable_concat_idents() {
17 feature_gate::emit_feature_err(&cx.parse_sess,
20 feature_gate::GateIssue::Language,
21 feature_gate::EXPLAIN_CONCAT_IDENTS);
25 cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
26 return DummyResult::any(sp);
29 let mut res_str = String::new();
30 for (i, e) in tts.iter().enumerate() {
33 TokenTree::Token(_, token::Comma) => {}
35 cx.span_err(sp, "concat_idents! expecting comma.");
36 return DummyResult::any(sp);
41 TokenTree::Token(_, token::Ident(ident, _)) =>
42 res_str.push_str(&ident.as_str()),
44 cx.span_err(sp, "concat_idents! requires ident args.");
45 return DummyResult::any(sp);
51 let ident = ast::Ident::new(Symbol::intern(&res_str), sp.apply_mark(cx.current_expansion.mark));
53 struct ConcatIdentsResult { ident: ast::Ident }
55 impl base::MacResult for ConcatIdentsResult {
56 fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
58 id: ast::DUMMY_NODE_ID,
59 node: ast::ExprKind::Path(None, ast::Path::from_ident(self.ident)),
60 span: self.ident.span,
61 attrs: ThinVec::new(),
65 fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
67 id: ast::DUMMY_NODE_ID,
68 node: ast::TyKind::Path(None, ast::Path::from_ident(self.ident)),
69 span: self.ident.span,
74 Box::new(ConcatIdentsResult { ident })