diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 016f3ab9da..320c71f33d 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -228,6 +228,18 @@ test "Allocator.resize" { } } +test "Allocator alloc and remap with zero-bit type" { + var values = try testing.allocator.alloc(void, 10); + defer testing.allocator.free(values); + + try testing.expectEqual(10, values.len); + const remaped = testing.allocator.remap(values, 200); + try testing.expect(remaped != null); + + values = remaped.?; + try testing.expectEqual(200, values.len); +} + /// Copy all of source into dest at position 0. /// dest.len must be >= source.len. /// If the slices overlap, dest.ptr must be <= src.ptr. diff --git a/lib/std/mem/Allocator.zig b/lib/std/mem/Allocator.zig index 1ad9533116..9995e65ad0 100644 --- a/lib/std/mem/Allocator.zig +++ b/lib/std/mem/Allocator.zig @@ -311,12 +311,15 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool { /// `allocation` may be an empty slice, in which case a new allocation is made. /// /// `new_len` may be zero, in which case the allocation is freed. +/// +/// If the allocation's elements' type is zero bytes sized, `allocation.len` is set to `new_len`. pub fn remap(self: Allocator, allocation: anytype, new_len: usize) t: { const Slice = @typeInfo(@TypeOf(allocation)).pointer; break :t ?[]align(Slice.alignment) Slice.child; } { const Slice = @typeInfo(@TypeOf(allocation)).pointer; const T = Slice.child; + const alignment = Slice.alignment; if (new_len == 0) { self.free(allocation); @@ -325,6 +328,11 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) t: { if (allocation.len == 0) { return null; } + if (@sizeOf(T) == 0) { + var new_memory = allocation; + new_memory.len = new_len; + return new_memory; + } const old_memory = mem.sliceAsBytes(allocation); // I would like to use saturating multiplication here, but LLVM cannot lower it // on WebAssembly: https://github.com/ziglang/zig/issues/9660