]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_builtin_macros/src/concat_bytes.rs
New upstream version 1.70.0+dfsg1
[rustc.git] / compiler / rustc_builtin_macros / src / concat_bytes.rs
index 4f1a7d709ff8c276900c255977d478fa9a3bec81..ba639c0a9fe3ca117c9ae10dbc0817c3fd6405bb 100644 (file)
@@ -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));