]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_builtin_macros/src/concat_bytes.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / compiler / rustc_builtin_macros / src / concat_bytes.rs
index 66e86bf2182672e0453f24aa3837623ea1a43b72..d1124145dcbbb663febddf26081de93812aa39d5 100644 (file)
@@ -2,18 +2,22 @@ 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;
 
 /// Emits errors for literal expressions that are invalid inside and outside of an array.
-fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_nested: bool) {
-    let ast::ExprKind::Lit(lit) = &expr.kind else {
-        unreachable!();
-    };
-    match lit.kind {
-        ast::LitKind::Char(_) => {
-            let mut err = cx.struct_span_err(expr.span, "cannot concatenate character literals");
-            if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
+fn invalid_type_err(
+    cx: &mut base::ExtCtxt<'_>,
+    token_lit: ast::token::Lit,
+    span: Span,
+    is_nested: bool,
+) {
+    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(
-                    expr.span,
+                    span,
                     "try using a byte character",
                     format!("b{}", snippet),
                     Applicability::MachineApplicable,
@@ -21,13 +25,13 @@ fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_ne
                 .emit();
             }
         }
-        ast::LitKind::Str(_, _) => {
-            let mut err = cx.struct_span_err(expr.span, "cannot concatenate string literals");
+        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(expr.span) {
+                if let Ok(snippet) = cx.sess.source_map().span_to_snippet(span) {
                     err.span_suggestion(
-                        expr.span,
+                        span,
                         "try using a byte string",
                         format!("b{}", snippet),
                         Applicability::MachineApplicable,
@@ -36,18 +40,18 @@ fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_ne
             }
             err.emit();
         }
-        ast::LitKind::Float(_, _) => {
-            cx.span_err(expr.span, "cannot concatenate float literals");
+        Ok(ast::LitKind::Float(_, _)) => {
+            cx.span_err(span, "cannot concatenate float literals");
         }
-        ast::LitKind::Bool(_) => {
-            cx.span_err(expr.span, "cannot concatenate boolean literals");
+        Ok(ast::LitKind::Bool(_)) => {
+            cx.span_err(span, "cannot concatenate boolean literals");
         }
-        ast::LitKind::Err => {}
-        ast::LitKind::Int(_, _) if !is_nested => {
-            let mut err = cx.struct_span_err(expr.span, "cannot concatenate numeric literals");
-            if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
+        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(
-                    expr.span,
+                    span,
                     "try wrapping the number in an array",
                     format!("[{}]", snippet),
                     Applicability::MachineApplicable,
@@ -55,17 +59,20 @@ fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_ne
             }
             err.emit();
         }
-        ast::LitKind::Int(
+        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(expr.span, "numeric literal is out of bounds");
+            cx.span_err(span, "numeric literal is out of bounds");
+        }
+        Ok(ast::LitKind::Int(_, _)) => {
+            cx.span_err(span, "numeric literal is not a `u8`");
         }
-        ast::LitKind::Int(_, _) => {
-            cx.span_err(expr.span, "numeric literal is not a `u8`");
+        Ok(ast::LitKind::ByteStr(_) | ast::LitKind::Byte(_)) => unreachable!(),
+        Err(err) => {
+            report_lit_error(&cx.sess.parse_sess, err, token_lit, span);
         }
-        _ => unreachable!(),
     }
 }
 
@@ -83,14 +90,14 @@ fn handle_array_element(
             *has_errors = true;
             None
         }
-        ast::ExprKind::Lit(ref lit) => match lit.kind {
-            ast::LitKind::Int(
+        ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
+            Ok(ast::LitKind::Int(
                 val,
                 ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
-            ) if val <= u8::MAX.into() => Some(val as u8),
+            )) if val <= u8::MAX.into() => Some(val as u8),
 
-            ast::LitKind::Byte(val) => Some(val),
-            ast::LitKind::ByteStr(_) => {
+            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")
@@ -102,12 +109,22 @@ fn handle_array_element(
             }
             _ => {
                 if !*has_errors {
-                    invalid_type_err(cx, expr, true);
+                    invalid_type_err(cx, token_lit, expr.span, true);
                 }
                 *has_errors = true;
                 None
             }
         },
+        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();
+            }
+            *has_errors = true;
+            None
+        }
         _ => {
             missing_literals.push(expr.span);
             None
@@ -127,8 +144,8 @@ pub fn expand_concat_bytes(
     let mut missing_literals = vec![];
     let mut has_errors = false;
     for e in es {
-        match e.kind {
-            ast::ExprKind::Array(ref exprs) => {
+        match &e.kind {
+            ast::ExprKind::Array(exprs) => {
                 for expr in exprs {
                     if let Some(elem) =
                         handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
@@ -137,10 +154,10 @@ pub fn expand_concat_bytes(
                     }
                 }
             }
-            ast::ExprKind::Repeat(ref expr, ref count) => {
-                if let ast::ExprKind::Lit(ast::Lit {
-                    kind: ast::LitKind::Int(count_val, _), ..
-                }) = count.value.kind
+            ast::ExprKind::Repeat(expr, count) => {
+                if let ast::ExprKind::Lit(token_lit) = count.value.kind
+                && let Ok(ast::LitKind::Int(count_val, _)) =
+                    ast::LitKind::from_token_lit(token_lit)
                 {
                     if let Some(elem) =
                         handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
@@ -153,20 +170,23 @@ pub fn expand_concat_bytes(
                     cx.span_err(count.value.span, "repeat count is not a positive number");
                 }
             }
-            ast::ExprKind::Lit(ref lit) => match lit.kind {
-                ast::LitKind::Byte(val) => {
+            &ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
+                Ok(ast::LitKind::Byte(val)) => {
                     accumulator.push(val);
                 }
-                ast::LitKind::ByteStr(ref bytes) => {
+                Ok(ast::LitKind::ByteStr(ref bytes)) => {
                     accumulator.extend_from_slice(&bytes);
                 }
                 _ => {
                     if !has_errors {
-                        invalid_type_err(cx, &e, false);
+                        invalid_type_err(cx, token_lit, e.span, false);
                     }
                     has_errors = true;
                 }
             },
+            ast::ExprKind::IncludedBytes(bytes) => {
+                accumulator.extend_from_slice(bytes);
+            }
             ast::ExprKind::Err => {
                 has_errors = true;
             }