But I don’t see this listed as a supported coercion. Anyone know if it is meant to work but is just undocumented? Or is it not intended to work and I shouldn’t rely on it?
// 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);
The title is misleading, there is no coertion from slice to array. There is from pointer to array to slice, but that’s trivial: a pointer to an array of length N is easily convertible to a slice of length N.
In this case slicing with comptime known bounds results in a pointer to an array because it provides more information than generating a slice. It’s peculiar, and a welcome addition when it was added to Zig, but again nothing particularly mindblowing, especially given my first point, that pointers to array coerce so slices (so you get more info if you want, otherwise the value will coerce to a slice without you having to do anything).
So actually, there’s no coercion here, there would instead be one if it were e.g. something like this:
// no change here
fn f() void {
var slice: []const usize = &.{1, 2, 3};
_ = g(slice[0..2]); // now a coercion from an array pointer to slice
}
// now takes a slice
fn g(buf: []const usize) usize {
// ...
}
Also, if the call in the original code was something like g(slice[0..3]) or g(slice[0..some_runtime_value]), it would not compile.
Best of all, I see no drawbacks to Zig setting the types this way. I have to say this is actually genius!