parent
7abab1efb2
commit
31731511c0
@ -72,6 +72,52 @@ fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_ne
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_array_element(
|
||||||
|
cx: &mut base::ExtCtxt<'_>,
|
||||||
|
has_errors: &mut bool,
|
||||||
|
missing_literals: &mut Vec<rustc_span::Span>,
|
||||||
|
expr: &P<rustc_ast::Expr>,
|
||||||
|
) -> Option<u8> {
|
||||||
|
match expr.kind {
|
||||||
|
ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => {
|
||||||
|
if !*has_errors {
|
||||||
|
cx.span_err(expr.span, "cannot concatenate doubly nested array");
|
||||||
|
}
|
||||||
|
*has_errors = true;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
||||||
|
ast::LitKind::Int(
|
||||||
|
val,
|
||||||
|
ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
|
||||||
|
) if val <= u8::MAX.into() => Some(val as u8),
|
||||||
|
|
||||||
|
ast::LitKind::Byte(val) => Some(val),
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
*has_errors = true;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if !*has_errors {
|
||||||
|
invalid_type_err(cx, expr, true);
|
||||||
|
}
|
||||||
|
*has_errors = true;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
missing_literals.push(expr.span);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn expand_concat_bytes(
|
pub fn expand_concat_bytes(
|
||||||
cx: &mut base::ExtCtxt<'_>,
|
cx: &mut base::ExtCtxt<'_>,
|
||||||
sp: rustc_span::Span,
|
sp: rustc_span::Span,
|
||||||
@ -88,49 +134,28 @@ pub fn expand_concat_bytes(
|
|||||||
match e.kind {
|
match e.kind {
|
||||||
ast::ExprKind::Array(ref exprs) => {
|
ast::ExprKind::Array(ref exprs) => {
|
||||||
for expr in exprs {
|
for expr in exprs {
|
||||||
match expr.kind {
|
if let Some(elem) =
|
||||||
ast::ExprKind::Array(_) => {
|
handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
|
||||||
if !has_errors {
|
{
|
||||||
cx.span_err(expr.span, "cannot concatenate doubly nested array");
|
accumulator.push(elem);
|
||||||
}
|
|
||||||
has_errors = true;
|
|
||||||
}
|
|
||||||
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
|
||||||
ast::LitKind::Int(
|
|
||||||
val,
|
|
||||||
ast::LitIntType::Unsuffixed
|
|
||||||
| ast::LitIntType::Unsigned(ast::UintTy::U8),
|
|
||||||
) if val <= u8::MAX.into() => {
|
|
||||||
accumulator.push(val as u8);
|
|
||||||
}
|
|
||||||
|
|
||||||
ast::LitKind::Byte(val) => {
|
|
||||||
accumulator.push(val);
|
|
||||||
}
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
has_errors = true;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
if !has_errors {
|
|
||||||
invalid_type_err(cx, expr, true);
|
|
||||||
}
|
|
||||||
has_errors = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
missing_literals.push(expr.span);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ast::ExprKind::Repeat(ref expr, ref count) => {
|
||||||
|
if let ast::ExprKind::Lit(ast::Lit {
|
||||||
|
kind: ast::LitKind::Int(count_val, _), ..
|
||||||
|
}) = count.value.kind
|
||||||
|
{
|
||||||
|
if let Some(elem) =
|
||||||
|
handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
|
||||||
|
{
|
||||||
|
for _ in 0..count_val {
|
||||||
|
accumulator.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cx.span_err(count.value.span, "repeat count is not a number");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
||||||
ast::LitKind::Byte(val) => {
|
ast::LitKind::Byte(val) => {
|
||||||
|
@ -39,4 +39,12 @@ fn main() {
|
|||||||
]);
|
]);
|
||||||
concat_bytes!(5u16); //~ ERROR cannot concatenate numeric literals
|
concat_bytes!(5u16); //~ ERROR cannot concatenate numeric literals
|
||||||
concat_bytes!([5u16]); //~ ERROR numeric literal is not a `u8`
|
concat_bytes!([5u16]); //~ ERROR numeric literal is not a `u8`
|
||||||
|
concat_bytes!([3; ()]); //~ ERROR repeat count is not a number
|
||||||
|
concat_bytes!([3; -2]); //~ ERROR repeat count is not a number
|
||||||
|
concat_bytes!([pie; -2]); //~ ERROR repeat count is not a number
|
||||||
|
concat_bytes!([pie; 2]); //~ ERROR expected a byte literal
|
||||||
|
concat_bytes!([2.2; 0]); //~ ERROR cannot concatenate float literals
|
||||||
|
concat_bytes!([5.5; ()]); //~ ERROR repeat count is not a number
|
||||||
|
concat_bytes!([[1, 2, 3]; 3]); //~ ERROR cannot concatenate doubly nested array
|
||||||
|
concat_bytes!([[42; 2]; 3]); //~ ERROR cannot concatenate doubly nested array
|
||||||
}
|
}
|
||||||
|
@ -127,5 +127,55 @@ error: numeric literal is not a `u8`
|
|||||||
LL | concat_bytes!([5u16]);
|
LL | concat_bytes!([5u16]);
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to 20 previous errors
|
error: repeat count is not a number
|
||||||
|
--> $DIR/concat-bytes-error.rs:42:23
|
||||||
|
|
|
||||||
|
LL | concat_bytes!([3; ()]);
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: repeat count is not a number
|
||||||
|
--> $DIR/concat-bytes-error.rs:43:23
|
||||||
|
|
|
||||||
|
LL | concat_bytes!([3; -2]);
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: repeat count is not a number
|
||||||
|
--> $DIR/concat-bytes-error.rs:44:25
|
||||||
|
|
|
||||||
|
LL | concat_bytes!([pie; -2]);
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: expected a byte literal
|
||||||
|
--> $DIR/concat-bytes-error.rs:45:20
|
||||||
|
|
|
||||||
|
LL | concat_bytes!([pie; 2]);
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: only byte literals (like `b"foo"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`
|
||||||
|
|
||||||
|
error: cannot concatenate float literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:46:20
|
||||||
|
|
|
||||||
|
LL | concat_bytes!([2.2; 0]);
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: repeat count is not a number
|
||||||
|
--> $DIR/concat-bytes-error.rs:47:25
|
||||||
|
|
|
||||||
|
LL | concat_bytes!([5.5; ()]);
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: cannot concatenate doubly nested array
|
||||||
|
--> $DIR/concat-bytes-error.rs:48:20
|
||||||
|
|
|
||||||
|
LL | concat_bytes!([[1, 2, 3]; 3]);
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error: cannot concatenate doubly nested array
|
||||||
|
--> $DIR/concat-bytes-error.rs:49:20
|
||||||
|
|
|
||||||
|
LL | concat_bytes!([[42; 2]; 3]);
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 28 previous errors
|
||||||
|
|
||||||
|
@ -3,5 +3,15 @@
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(concat_bytes!(), &[]);
|
assert_eq!(concat_bytes!(), &[]);
|
||||||
assert_eq!(concat_bytes!(b'A', b"BC", [68, b'E', 70]), b"ABCDEF");
|
assert_eq!(
|
||||||
|
concat_bytes!(b'A', b"BC", [68, b'E', 70], [b'G'; 1], [72; 2], [73u8; 3], [65; 0]),
|
||||||
|
b"ABCDEFGHHIII",
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
concat_bytes!(
|
||||||
|
concat_bytes!(b"AB", b"CD"),
|
||||||
|
concat_bytes!(b"EF", b"GH"),
|
||||||
|
),
|
||||||
|
b"ABCDEFGH",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user