`ArrayList(u0).appendSlice(list, &.{0, 0, 0})` `panic: @memcpy arguments alias`
Zig Version
0.14.0-dev.1765+73de620ad
Steps to Reproduce and Observed Behavior
--- lib/std/array_list.zig.orig 2024-10-06 16:53:25.000000000 +1000
+++ lib/std/array_list.zig 2024-10-10 18:40:01.106947099 +1000
@@ -2170,17 +2170,15 @@
test "ArrayList(u0)" {
// An ArrayList on zero-sized types should not need to allocate
const a = testing.failing_allocator;
var list = ArrayList(u0).init(a);
defer list.deinit();
- try list.append(0);
- try list.append(0);
- try list.append(0);
+ try list.appendSlice(&.{0, 0, 0});
try testing.expectEqual(list.items.len, 3);
var count: usize = 0;
for (list.items) |x| {
try testing.expectEqual(x, 0);
count += 1;
}
$ zig test --test-filter 'array_list.test.ArrayList(u0)' lib/std/std.zig
thread 35184 panic: @memcpy arguments alias
lib/std/array_list.zig:317:42: 0x11816b2 in appendSliceAssumeCapacity (test)
@memcpy(self.items[old_len..][0..items.len], items);
^
lib/std/array_list.zig:306:43: 0x118143f in appendSlice (test)
self.appendSliceAssumeCapacity(items);
^
lib/std/array_list.zig:2177:25: 0x11809d4 in test.ArrayList(u0) (test)
try list.appendSlice(&.{0, 0, 0});
^
Expected Behavior
I think slices of zero-sized types shouldn't ever be considered aliased, even if they start from the exact same address.
Maybe if the bit size of element type of memcpy is zero then memcpy should be a noop?
Small repro: https://godbolt.org/z/K6f3sE9z6
well, if you think about it, is technically correct since, in the allocator interface you can see that if you try to allocate 0 bytes: it just returns the maximum address possible with backwarf alignement. i.e: u0 has an alignement of 1 and thus returns the address of std.math.maxInt(usize), and when the arraylist tries to allocate a new slice for the list it'll try to allocate 0*n bytes, thus 0 bytes and it will return the same value specified above.
Now yes this shouldn't be a bug and @memcpy should just be a no-op on 0 bytes types. Or change the ArrayList type to just change the 'len' field of the internal slice on 0-sized types.