Because new_len is a length, not an index. Your suggested alternative does a different slice.
@memcpy(self.items[old_len..][0..items.len], items);
Is called a “slice by length”, and is equivalent to: @memcpy(self.items[old_len..old_len + items.len], items); Not a slice by index, which is what you suggested: @memcpy(self.items[old_len..new_len], items);
// 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);