]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_builtin_macros/src/concat_idents.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / compiler / rustc_builtin_macros / src / concat_idents.rs
1 use rustc_ast as ast;
2 use rustc_ast::ptr::P;
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};
7 use rustc_span::Span;
8
9 pub fn expand_concat_idents<'cx>(
10 cx: &'cx mut ExtCtxt<'_>,
11 sp: Span,
12 tts: TokenStream,
13 ) -> Box<dyn base::MacResult + 'cx> {
14 if tts.is_empty() {
15 cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
16 return DummyResult::any(sp);
17 }
18
19 let mut res_str = String::new();
20 for (i, e) in tts.into_trees().enumerate() {
21 if i & 1 == 1 {
22 match e {
23 TokenTree::Token(Token { kind: token::Comma, .. }) => {}
24 _ => {
25 cx.span_err(sp, "concat_idents! expecting comma.");
26 return DummyResult::any(sp);
27 }
28 }
29 } else {
30 if let TokenTree::Token(token) = e {
31 if let Some((ident, _)) = token.ident() {
32 res_str.push_str(&ident.name.as_str());
33 continue;
34 }
35 }
36
37 cx.span_err(sp, "concat_idents! requires ident args.");
38 return DummyResult::any(sp);
39 }
40 }
41
42 let ident = Ident::new(Symbol::intern(&res_str), cx.with_call_site_ctxt(sp));
43
44 struct ConcatIdentsResult {
45 ident: Ident,
46 }
47
48 impl base::MacResult for ConcatIdentsResult {
49 fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
50 Some(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(),
55 tokens: None,
56 }))
57 }
58
59 fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
60 Some(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,
64 tokens: None,
65 }))
66 }
67 }
68
69 Box::new(ConcatIdentsResult { ident })
70 }