1 use rustc_data_structures::thin_vec::ThinVec;
4 use syntax::ext::base::*;
6 use syntax::feature_gate;
7 use syntax::parse::token;
10 use syntax_pos::symbol::Symbol;
11 use syntax::tokenstream::TokenTree;
13 pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
16 -> Box<dyn base::MacResult + 'cx> {
17 if !cx.ecfg.enable_concat_idents() {
18 feature_gate::emit_feature_err(&cx.parse_sess,
21 feature_gate::GateIssue::Language,
22 feature_gate::EXPLAIN_CONCAT_IDENTS);
26 cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
27 return DummyResult::expr(sp);
30 let mut res_str = String::new();
31 for (i, e) in tts.iter().enumerate() {
34 TokenTree::Token(_, token::Comma) => {}
36 cx.span_err(sp, "concat_idents! expecting comma.");
37 return DummyResult::expr(sp);
42 TokenTree::Token(_, token::Ident(ident, _)) =>
43 res_str.push_str(&ident.as_str()),
45 cx.span_err(sp, "concat_idents! requires ident args.");
46 return DummyResult::expr(sp);
52 let ident = ast::Ident::new(Symbol::intern(&res_str), sp.apply_mark(cx.current_expansion.mark));
54 struct ConcatIdentsResult { ident: ast::Ident }
56 impl base::MacResult for ConcatIdentsResult {
57 fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
59 id: ast::DUMMY_NODE_ID,
60 node: ast::ExprKind::Path(None, ast::Path::from_ident(self.ident)),
61 span: self.ident.span,
62 attrs: ThinVec::new(),
66 fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
68 id: ast::DUMMY_NODE_ID,
69 node: ast::TyKind::Path(None, ast::Path::from_ident(self.ident)),
70 span: self.ident.span,
75 Box::new(ConcatIdentsResult { ident })