It’s interesting that the arr[2..4] does not result in an array pointer, even though both ends of the range are comptime-known. Does that mean that Zig special-cases specifically on [0..n]? Edit: see below reply
With that said, it seems to be somewhat common to represent “at index i, take a slice of n elements” like so in Zig:
Slices do not coerce to array pointers, it is the other way around. When the slice size is comptime-known, like in arr[2..4], this results in a pointer to array, which then may transparently coerce to a slice. Since you are explicitly specifying that slice is []const u8, you cannot then pass it to testArrPtr. If you remove the type (and add the missing ! in testArrPtr’s return type), the original code compiles:
// If you slice with comptime-known start and end positions, the result is
// a pointer to an array, rather than a slice.
const array_ptr = array[0..array.len];
try expect(@TypeOf(array_ptr) == *[array.len]i32);
// You can perform a slice-by-length by slicing twice. This allows the compiler
// to perform some optimisations like recognising a comptime-known length when
// the start position is only known at runtime.
var runtime_start: usize = 1;
_ = &runtime_start;
const length = 2;
const array_ptr_len = array[runtime_start..][0..length];
try expect(@TypeOf(array_ptr_len) == *[length]i32);