diff options
Diffstat (limited to 'compiler/rustc_builtin_macros/src/concat.rs')
-rw-r--r-- | compiler/rustc_builtin_macros/src/concat.rs | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs index 7da9bdc38..b92964d03 100644 --- a/compiler/rustc_builtin_macros/src/concat.rs +++ b/compiler/rustc_builtin_macros/src/concat.rs @@ -4,6 +4,8 @@ use rustc_expand::base::{self, DummyResult}; use rustc_session::errors::report_lit_error; use rustc_span::symbol::Symbol; +use crate::errors; + pub fn expand_concat( cx: &mut base::ExtCtxt<'_>, sp: rustc_span::Span, @@ -31,7 +33,7 @@ pub fn expand_concat( accumulator.push_str(&b.to_string()); } Ok(ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..)) => { - cx.span_err(e.span, "cannot concatenate a byte string literal"); + cx.emit_err(errors::ConcatBytestr { span: e.span }); has_errors = true; } Ok(ast::LitKind::Err) => { @@ -42,8 +44,20 @@ pub fn expand_concat( has_errors = true; } }, + // We also want to allow negative numeric literals. + ast::ExprKind::Unary(ast::UnOp::Neg, ref expr) if let ast::ExprKind::Lit(token_lit) = expr.kind => { + match ast::LitKind::from_token_lit(token_lit) { + Ok(ast::LitKind::Int(i, _)) => accumulator.push_str(&format!("-{i}")), + Ok(ast::LitKind::Float(f, _)) => accumulator.push_str(&format!("-{f}")), + Err(err) => { + report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span); + has_errors = true; + } + _ => missing_literal.push(e.span), + } + } ast::ExprKind::IncludedBytes(..) => { - cx.span_err(e.span, "cannot concatenate a byte string literal") + cx.emit_err(errors::ConcatBytestr { span: e.span }); } ast::ExprKind::Err => { has_errors = true; @@ -53,10 +67,9 @@ pub fn expand_concat( } } } + 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(); + cx.emit_err(errors::ConcatMissingLiteral { spans: missing_literal }); return DummyResult::any(sp); } else if has_errors { return DummyResult::any(sp); |