Extracted from #3770.
When the index used for loading or storing to a sentinel-terminated slice or array is comptime-known to be equal to the length, we know at compile-time the value is the sentinel. So, loading should give a comptime value of the sentinel, with no runtime code emitted, and storing should be a no-op with a safety check to make sure the stored value is equal to the sentinel value.
const std = @import("std");
const expect = std.testing.expect;
test "comptime known load of sentinel-terminated slice" {
// here we have a normal array
var buf: [50]u8 = undefined;
buf[0] = 'a';
buf[1] = 'b';
buf[2] = 'c';
buf[3] = 0;
// now we obtain a null terminated slice:
const slice = buf[0..3 :0];
comptime expect(slice[3] == 0);
}
The safety check thing:
test "trip runtime safety check" {
// here we have a normal array
var buf: [50]u8 = undefined;
buf[0] = 'a';
buf[1] = 'b';
buf[2] = 'c';
buf[3] = 0;
// now we obtain a null terminated slice:
const slice = buf[0..3 :0];
var runtime_elem: u8 = 42;
slice[3] = runtime_elem; // panic: mangled the sentinel value
}
Potentially could be further improved:
test "trip runtime safety check 2" {
// here we have a normal array
var buf: [50]u8 = undefined;
buf[0] = 'a';
buf[1] = 'b';
buf[2] = 'c';
buf[3] = 0;
// now we obtain a null terminated slice:
const slice = buf[0..3 :0];
var runtime_elem: u8 = 42;
var runtime_index: usize = 3;
slice[runtime_index] = runtime_elem; // panic: mangled the sentinel value
}
Extracted from #3770.
When the index used for loading or storing to a sentinel-terminated slice or array is comptime-known to be equal to the length, we know at compile-time the value is the sentinel. So, loading should give a comptime value of the sentinel, with no runtime code emitted, and storing should be a no-op with a safety check to make sure the stored value is equal to the sentinel value.
The safety check thing:
Potentially could be further improved: