]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_builtin_macros/src/concat_idents.rs
Auto merge of #104975 - JakobDegen:custom_mir_let, r=oli-obk
[rust.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 }