Question about ArrayList.appendSliceAssumeCapacity

While checking how ArrayList works I came across appendSliceAssumeCapacity

   pub fn appendSliceAssumeCapacity(self: *Self, items: []const T) void {
            const old_len = self.items.len;
            const new_len = old_len + items.len;
            assert(new_len <= self.capacity);
            self.items.len = new_len;
            @memcpy(self.items[old_len..][0..items.len], items);
        }

My question is;
why it’s
@memcpy(self.items[old_len..][0..items.len], items);
and not
@memcpy(self.items[old_len..new_len], items);

am I missing something ?

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);

This is from the docs:

    // 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);
4 Likes