`ArrayList.ensureUnusedCapacity` in `FixedBufferAllocator` breaks in comptime
Zig Version
0.12.0-dev.3125+a7a5f4cf4
Steps to Reproduce and Observed Behavior
Call ArrayList.ensureUnusedCapacity in comptime.
Get an error:
/home/bulby/zig-0.12.0-dev/lib/std/mem.zig:3781:18: error: unable to evaluate comptime expression
const addr = @intFromPtr(ptr);
^~~~~~~~~~~~~~~~
/home/bulby/zig-0.12.0-dev/lib/std/mem.zig:3781:30: note: operation is runtime due to this operand
const addr = @intFromPtr(ptr);
^~~
/home/bulby/zig-0.12.0-dev/lib/std/heap.zig:426:50: note: called from here
const adjust_off = mem.alignPointerOffset(self.buffer.ptr + self.end_index, ptr_align) orelse return null;
~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/bulby/zig-0.12.0-dev/lib/std/mem/Allocator.zig:86:29: note: called from here
return self.vtable.alloc(self.ptr, len, ptr_align, ret_addr);
~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/bulby/zig-0.12.0-dev/lib/std/mem/Allocator.zig:225:35: note: called from here
const byte_ptr = self.rawAlloc(byte_count, log2a(alignment), return_address) orelse return Error.OutOfMemory;
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/bulby/zig-0.12.0-dev/lib/std/mem/Allocator.zig:211:40: note: called from here
return self.allocBytesWithAlignment(alignment, byte_count, return_address);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/bulby/zig-0.12.0-dev/lib/std/mem/Allocator.zig:205:75: note: called from here
const ptr: [*]align(a) T = @ptrCast(try self.allocWithSizeAndAlignment(@sizeOf(T), a, n, return_address));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/bulby/zig-0.12.0-dev/lib/std/mem/Allocator.zig:193:41: note: called from here
return self.allocAdvancedWithRetAddr(T, alignment, n, @returnAddress());
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/bulby/zig-0.12.0-dev/lib/std/array_list.zig:457:67: note: called from here
const new_memory = try self.allocator.alignedAlloc(T, alignment, new_capacity);
~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/bulby/zig-0.12.0-dev/lib/std/array_list.zig:434:51: note: called from here
return self.ensureTotalCapacityPrecise(better_capacity);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
/home/bulby/zig-0.12.0-dev/lib/std/array_list.zig:468:44: note: called from here
return self.ensureTotalCapacity(try addOrOom(self.items.len, additional_count));
~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.zig:9:38: note: called from here
try list.ensureUnusedCapacity(10);
~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
code:
const std = @import("std");
test "it just doesn't work" {
comptime {
var buf: [65536]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&buf);
const alloc = fba.allocator();
var list = std.ArrayList(i32).init(alloc);
try list.ensureUnusedCapacity(10);
}
}
Expected Behavior
This should succeed as FBA is supposed to work at comptime.
related to: #16564 #16488
issue with FBA I guess?
Trying to parse xml at comptime, happened to me too with ArrayList.ensureTotalCapacity()
zig version: 0.14.0-dev.121+ab4c461b7
I found a workaround (at least for my machine, can't really test for others): using an ArrayListAligned with an alignment of std.mem.Alignment.@"1" seems to fix it.
Besides that, it seems like @intFromPtr() just doesn't work on a comptime variable's or constant's address.
Did a bit more research on the issues here, this is a result of the behavior described here: https://github.com/ziglang/zig/issues/15080#issuecomment-1484068134.