For curiosity, here's an array concatenation macro that supports unpacking (limited to a finite number of sizes, this macro is small and can be expanded).
I have nothing to claim about the performance or zero-costiness of this compared to any other solution (profile to know). If you use fixed size arrays all the way, all bounds checking happens at compile time.
First usage example:
fn main() {
let data = [0, 1, 2, 3, 4, 5, 6, 7, 8];
println!("{:?}", concat_arrays!([1, 2, 3] [4] [5, 6]));
// [1, 2, 3, 4, 5, 6]
println!("{:?}", concat_arrays!(data[3..];3 [-1] data;3));
// [3, 4, 5, -1, 0, 1, 2]
// let's look at the macro expansion of the last one
println!("{}", concat_arrays!(@build stringify [] data[3..];3 [-1] data;3));
// [ data[3..][0] , data[3..][1] , data[3..][2] , -1 , data[0] , data[1] , data[2] ]
}
Then implementation: (playground link)
/// Concatenate array literals and fixed-size unpacked parts of arrays and slices
///
/// Usage: `concat_arrays!(fragments)`
/// where each fragment is either an array literal: `[x, y, z]`
/// or an expression and how many elements to unpack: `expression;N`
/// where `N` must be an integer literal
///
/// See: https://gitlab.com/snippets/27095
/// for a script to generate a macro supporting many more arguments.
macro_rules! concat_arrays {
// last step -> build an expression
(@build as_expr [$($t:expr),*]) => {
[$($t),*]
};
(@build $m:ident [$($t:expr),*]) => {
$m!([$($t),*])
};
(@build $m:ident [$($t:expr),*] [$($e:expr),+] $($more:tt)*) => {
concat_arrays!(@build $m [$($t,)* $($e),*] $($more)*)
};
(@build $m:ident [$($t:expr),*] $e:expr;1 $($more:tt)*) => {
concat_arrays!(@build $m [$($t,)* $e[0]] $($more)*)
};
(@build $m:ident [$($t:expr),*] $e:expr;2 $($more:tt)*) => {
concat_arrays!(@build $m [$($t,)* $e[0], $e[1]] $($more)*)
};
(@build $m:ident [$($t:expr),*] $e:expr;3 $($more:tt)*) => {
concat_arrays!(@build $m [$($t,)* $e[0], $e[1], $e[2]] $($more)*)
};
(@build $m:ident [$($t:expr),*] $e:expr;4 $($more:tt)*) => {
concat_arrays!(@build $m [$($t,)* $e[0], $e[1], $e[2], $e[3]] $($more)*)
};
(@build $m:ident [$($t:expr),*] $e:expr;5 $($more:tt)*) => {
concat_arrays!(@build $m [$($t,)* $e[0], $e[1], $e[2], $e[3], $e[4]] $($more)*)
};
// user facing case
($($t:tt)+) => {
concat_arrays!(@build as_expr [] $($t)+)
}
}
Applied to your question, I'd do this:
concat_arrays!(bar[1..];4 taz[1..];4)
Which is succinct, but sure, it has some problems like for example being in a syntax that's idiosyncratic of the particular macro, and the problems that stem from the 4
having to be a literal, not only that but a literal from a finite list.
Edited:
See expanded macro, including script to generate a macro supporting a pre-defined number of arguments which can be much larger then the example given here.