inline compile error: indexing into empty slice is not allowed
Zig Version
0.13.0
Steps to Reproduce and Observed Behavior
inline function bisect_right cause error: indexing into empty slice is not allowed
pub fn bisect_right(arr: []const u8, target: usize) usize {
var start: usize = 0;
var end: usize = arr.len;
while (start < end) {
const mid = (start + end) / 2;
if (arr[mid] < target) {
start = mid + 1;
} else {
end = mid;
}
}
return start;
}
pub inline fn inline_bisect_right(arr: []const u8, target: usize) usize {
var start: usize = 0;
var end: usize = arr.len;
while (start < end) {
const mid = (start + end) / 2;
if (arr[mid] < target) {
start = mid + 1;
} else {
end = mid;
}
}
return start;
}
test "inline bisect const compile failed" {
const s = [_]u8{};
_ = inline_bisect_right(&s, 1);
}
test "inline bisect var compile success" {
var s = [_]u8{};
_ = inline_bisect_right(&s, 1);
}
test "inline bisect ok" {
const s = [_]u8{1};
_ = inline_bisect_right(&s, 1);
}
test "bisect ok" {
const s0 = [_]u8{0};
_ = bisect_right(&s0, 1);
const s1 = [_]u8{1};
_ = bisect_right(&s1, 1);
}
Expected Behavior
should not all of this behavior same as not inline annotated?
As documented in https://ziglang.org/documentation/master/#inline-fn, "arguments at an inline function callsite which are compile-time known are treated as Compile Time Parameters."
s0 is comptime-known in test "bisect ok", however the variables start and end in inline_bisect_right are var, so the condition in while (start < end) is only resolved at runtime.
Therefore the loop body is analyzed and arr[mid] is found, which triggers the compile error.
This seems not like a bug, but like the intended semantics to me.
Note that if you're unsure whether something is a bug, you can also ask in one of the community spaces.
As documented in https://ziglang.org/documentation/master/#inline-fn, "arguments at an inline function callsite which are compile-time known are treated as Compile Time Parameters."
s0iscomptime-known intest "bisect ok", however the variablesstartandendininline_bisect_rightarevar, so the condition inwhile (start < end)is only resolved at runtime. Therefore the loop body is analyzed andarr[mid]is found, which triggers the compile error. This seems not like a bug, but like the intended semantics to me. Note that if you're unsure whether something is a bug, you can also ask in one of the community spaces.
Yeah, when i analyzed the code, found the compiler don't know it's impossible go into loop when passing zero length slice. But is possible to provide some information to tell compiler to make code perform consistently?
But is possible to provide some information to tell compiler to make code perform consistently?
For your concrete example you can explicitly tell the compiler by adding an early return if (arr.len == 0) return start; before the loop. If arr is comptime-known, then arr.len is as well.
In the general case, the compiler doesn't want to try doing runtime work at comptime, and so it "gives up" and demotes code to runtime as soon as a runtime value is involved.
If you really want to use the inline keyword, you'll probably have to bend your code around this limitation.
Note that the inline keyword is discouraged in general:
It is generally better to let the compiler decide when to inline a function [...] Note that
inlineactually restricts what the compiler is allowed to do. This can harm binary size, compilation speed, and even runtime performance.