summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_builtin_macros/src/concat_bytes.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_builtin_macros/src/concat_bytes.rs')
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs77
1 files changed, 27 insertions, 50 deletions
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index 4f1a7d709..ba639c0a9 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -1,10 +1,11 @@
use rustc_ast as ast;
use rustc_ast::{ptr::P, tokenstream::TokenStream};
-use rustc_errors::Applicability;
use rustc_expand::base::{self, DummyResult};
use rustc_session::errors::report_lit_error;
use rustc_span::Span;
+use crate::errors;
+
/// Emits errors for literal expressions that are invalid inside and outside of an array.
fn invalid_type_err(
cx: &mut base::ExtCtxt<'_>,
@@ -12,62 +13,46 @@ fn invalid_type_err(
span: Span,
is_nested: bool,
) {
+ use errors::{
+ ConcatBytesInvalid, ConcatBytesInvalidSuggestion, ConcatBytesNonU8, ConcatBytesOob,
+ };
+ let snippet = cx.sess.source_map().span_to_snippet(span).ok();
match ast::LitKind::from_token_lit(token_lit) {
Ok(ast::LitKind::Char(_)) => {
- let mut err = cx.struct_span_err(span, "cannot concatenate character literals");
- if let Ok(snippet) = cx.sess.source_map().span_to_snippet(span) {
- err.span_suggestion(
- span,
- "try using a byte character",
- format!("b{}", snippet),
- Applicability::MachineApplicable,
- )
- .emit();
- }
+ let sugg =
+ snippet.map(|snippet| ConcatBytesInvalidSuggestion::CharLit { span, snippet });
+ cx.sess.emit_err(ConcatBytesInvalid { span, lit_kind: "character", sugg });
}
Ok(ast::LitKind::Str(_, _)) => {
- let mut err = cx.struct_span_err(span, "cannot concatenate string literals");
// suggestion would be invalid if we are nested
- if !is_nested {
- if let Ok(snippet) = cx.sess.source_map().span_to_snippet(span) {
- err.span_suggestion(
- span,
- "try using a byte string",
- format!("b{}", snippet),
- Applicability::MachineApplicable,
- );
- }
- }
- err.emit();
+ let sugg = if !is_nested {
+ snippet.map(|snippet| ConcatBytesInvalidSuggestion::StrLit { span, snippet })
+ } else {
+ None
+ };
+ cx.emit_err(ConcatBytesInvalid { span, lit_kind: "string", sugg });
}
Ok(ast::LitKind::Float(_, _)) => {
- cx.span_err(span, "cannot concatenate float literals");
+ cx.emit_err(ConcatBytesInvalid { span, lit_kind: "float", sugg: None });
}
Ok(ast::LitKind::Bool(_)) => {
- cx.span_err(span, "cannot concatenate boolean literals");
+ cx.emit_err(ConcatBytesInvalid { span, lit_kind: "boolean", sugg: None });
}
Ok(ast::LitKind::Err) => {}
Ok(ast::LitKind::Int(_, _)) if !is_nested => {
- let mut err = cx.struct_span_err(span, "cannot concatenate numeric literals");
- if let Ok(snippet) = cx.sess.source_map().span_to_snippet(span) {
- err.span_suggestion(
- span,
- "try wrapping the number in an array",
- format!("[{}]", snippet),
- Applicability::MachineApplicable,
- );
- }
- err.emit();
+ let sugg =
+ snippet.map(|snippet| ConcatBytesInvalidSuggestion::IntLit { span: span, snippet });
+ cx.emit_err(ConcatBytesInvalid { span, lit_kind: "numeric", sugg });
}
Ok(ast::LitKind::Int(
val,
ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
)) => {
assert!(val > u8::MAX.into()); // must be an error
- cx.span_err(span, "numeric literal is out of bounds");
+ cx.emit_err(ConcatBytesOob { span });
}
Ok(ast::LitKind::Int(_, _)) => {
- cx.span_err(span, "numeric literal is not a `u8`");
+ cx.emit_err(ConcatBytesNonU8 { span });
}
Ok(ast::LitKind::ByteStr(..) | ast::LitKind::Byte(_)) => unreachable!(),
Err(err) => {
@@ -85,7 +70,7 @@ fn handle_array_element(
match expr.kind {
ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => {
if !*has_errors {
- cx.span_err(expr.span, "cannot concatenate doubly nested array");
+ cx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false });
}
*has_errors = true;
None
@@ -99,10 +84,7 @@ fn handle_array_element(
Ok(ast::LitKind::Byte(val)) => Some(val),
Ok(ast::LitKind::ByteStr(..)) => {
if !*has_errors {
- cx.struct_span_err(expr.span, "cannot concatenate doubly nested array")
- .note("byte strings are treated as arrays of bytes")
- .help("try flattening the array")
- .emit();
+ cx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: true });
}
*has_errors = true;
None
@@ -117,10 +99,7 @@ fn handle_array_element(
},
ast::ExprKind::IncludedBytes(..) => {
if !*has_errors {
- cx.struct_span_err(expr.span, "cannot concatenate doubly nested array")
- .note("byte strings are treated as arrays of bytes")
- .help("try flattening the array")
- .emit();
+ cx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false });
}
*has_errors = true;
None
@@ -167,7 +146,7 @@ pub fn expand_concat_bytes(
}
}
} else {
- cx.span_err(count.value.span, "repeat count is not a positive number");
+ cx.emit_err(errors::ConcatBytesBadRepeat {span: count.value.span });
}
}
&ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
@@ -196,9 +175,7 @@ pub fn expand_concat_bytes(
}
}
if !missing_literals.is_empty() {
- let mut err = cx.struct_span_err(missing_literals, "expected a byte literal");
- err.note("only byte literals (like `b\"foo\"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`");
- err.emit();
+ cx.emit_err(errors::ConcatBytesMissingLiteral { spans: missing_literals });
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
} else if has_errors {
return base::MacEager::expr(DummyResult::raw_expr(sp, true));