about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros/src/concat.rs
diff options
context:
space:
mode:
authormark <markm@cs.wisc.edu>2020-08-27 22:58:48 -0500
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2020-08-30 18:45:07 +0300
commit9e5f7d5631b8f4009ac1c693e585d4b7108d4275 (patch)
tree158a05eb3f204a8e72939b58427d0c2787a4eade /compiler/rustc_builtin_macros/src/concat.rs
parentdb534b3ac286cf45688c3bbae6aa6e77439e52d2 (diff)
downloadrust-9e5f7d5631b8f4009ac1c693e585d4b7108d4275.tar.gz
rust-9e5f7d5631b8f4009ac1c693e585d4b7108d4275.zip
mv compiler to compiler/
Diffstat (limited to 'compiler/rustc_builtin_macros/src/concat.rs')
-rw-r--r--compiler/rustc_builtin_macros/src/concat.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
new file mode 100644
index 00000000000..e5077d93674
--- /dev/null
+++ b/compiler/rustc_builtin_macros/src/concat.rs
@@ -0,0 +1,65 @@
+use rustc_ast as ast;
+use rustc_ast::tokenstream::TokenStream;
+use rustc_expand::base::{self, DummyResult};
+use rustc_span::symbol::Symbol;
+
+use std::string::String;
+
+pub fn expand_concat(
+    cx: &mut base::ExtCtxt<'_>,
+    sp: rustc_span::Span,
+    tts: TokenStream,
+) -> Box<dyn base::MacResult + 'static> {
+    let es = match base::get_exprs_from_tts(cx, sp, tts) {
+        Some(e) => e,
+        None => return DummyResult::any(sp),
+    };
+    let mut accumulator = String::new();
+    let mut missing_literal = vec![];
+    let mut has_errors = false;
+    for e in es {
+        match e.kind {
+            ast::ExprKind::Lit(ref lit) => match lit.kind {
+                ast::LitKind::Str(ref s, _) | ast::LitKind::Float(ref s, _) => {
+                    accumulator.push_str(&s.as_str());
+                }
+                ast::LitKind::Char(c) => {
+                    accumulator.push(c);
+                }
+                ast::LitKind::Int(
+                    i,
+                    ast::LitIntType::Unsigned(_)
+                    | ast::LitIntType::Signed(_)
+                    | ast::LitIntType::Unsuffixed,
+                ) => {
+                    accumulator.push_str(&i.to_string());
+                }
+                ast::LitKind::Bool(b) => {
+                    accumulator.push_str(&b.to_string());
+                }
+                ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..) => {
+                    cx.span_err(e.span, "cannot concatenate a byte string literal");
+                }
+                ast::LitKind::Err(_) => {
+                    has_errors = true;
+                }
+            },
+            ast::ExprKind::Err => {
+                has_errors = true;
+            }
+            _ => {
+                missing_literal.push(e.span);
+            }
+        }
+    }
+    if !missing_literal.is_empty() {
+        let mut err = cx.struct_span_err(missing_literal, "expected a literal");
+        err.note("only literals (like `\"foo\"`, `42` and `3.14`) can be passed to `concat!()`");
+        err.emit();
+        return DummyResult::any(sp);
+    } else if has_errors {
+        return DummyResult::any(sp);
+    }
+    let sp = cx.with_def_site_ctxt(sp);
+    base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
+}