From 94dff4e5827e2ef4a13f4f44aa2e2d4bf0a0dbcf Mon Sep 17 00:00:00 2001 From: Mathias Fiedler Date: Sat, 30 Aug 2025 11:28:13 +0200 Subject: [PATCH] Fix size check when composed array is too long Ensure the union fields of ArrayConcatComposed have matching sizes by updating the size validations in the macros concat_array and split_array. Previously, the size check in concat_arrays were only catching cases where the inferred result type was shorter than the sum of input array lengths. It failed to detect longer result arrays, since the size of Self matches its biggest union field. For example, this compiled without error: let c: [u32; 6] = concat_arrays!([1, 2, 3], [4, 5]); This led to arrays containing undefined values. The same applied for split_array when the input array is longer than the sum of the output array lengths. While this did not lead to undefined values, the exceeding elements would not be dropped. --- src/lib.rs | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6c2051d..a520f13 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,21 @@ macro_rules! concat_arrays_size { } /// Concatenates provided arrays. +/// +/// The macro verifies that the combined length of the input arrays matches the length of the result array. +/// The examples below will fail to compile as the input arrays are either too short or too long. +/// ```compile_fail +/// # #[macro_use] extern crate array_concat; +/// # fn main() { +/// let c: [u32; 6] = concat_arrays!([1, 2, 3], [4, 5]); // too short +/// # } +/// ``` +/// ```compile_fail +/// # #[macro_use] extern crate array_concat; +/// # fn main() { +/// let c: [u32; 6] = concat_arrays!([1, 2, 3], [4, 5, 6, 7]); // too long +/// # } +/// ``` #[macro_export] macro_rules! concat_arrays { ($( $array:expr ),*) => ({ @@ -39,7 +54,7 @@ macro_rules! concat_arrays { } impl ArrayConcatComposed { - const PANIC: bool = $crate::_const_assert_same_size::<[T; N], Self>(); + const PANIC: bool = $crate::_const_assert_same_size::<[T; N], ArrayConcatDecomposed::>(); #[inline(always)] const fn have_same_size(&self) -> bool { @@ -89,6 +104,21 @@ macro_rules! flatten_split { } /// Split the provided array into the specified sizes. +/// +/// The macro verifies that the length of the input array matches the combined length of the result arrays. +/// The examples below will fail to compile as the input array is either too short or too long. +/// ```compile_fail +/// # #[macro_use] extern crate array_concat; +/// # fn main() { +/// let (left, right): ([u32; 3], [u32; 4]) = split_array!([1, 2, 3, 4, 5, 6], 3, 4); // too short +/// # } +/// ``` +/// ```compile_fail +/// # #[macro_use] extern crate array_concat; +/// # fn main() { +/// let (left, right): ([u32; 3], [u32; 2]) = split_array!([1, 2, 3, 4, 5, 6], 3, 2); // too long +/// # } +/// ``` #[macro_export] macro_rules! split_array { ($array:expr, $size:expr) => ($array); @@ -141,7 +171,7 @@ macro_rules! split_array { } impl ArrayConcatComposed { - const PANIC: bool = $crate::_const_assert_same_size::<[T; N], Self>(); + const PANIC: bool = $crate::_const_assert_same_size::<[T; N], ArrayConcatDecomposed::>(); #[inline(always)] const fn have_same_size(&self) -> bool {