zig icon indicating copy to clipboard operation
zig copied to clipboard

`ArrayList.ensureUnusedCapacity` in `FixedBufferAllocator` breaks in comptime

Open TheDrawingCoder-Gamer opened this issue 1 year ago • 2 comments

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.

TheDrawingCoder-Gamer avatar Mar 02 '24 15:03 TheDrawingCoder-Gamer

related to: #16564 #16488

issue with FBA I guess?

TheDrawingCoder-Gamer avatar Mar 02 '24 17:03 TheDrawingCoder-Gamer

Trying to parse xml at comptime, happened to me too with ArrayList.ensureTotalCapacity() zig version: 0.14.0-dev.121+ab4c461b7

ssmid avatar Jul 23 '24 05:07 ssmid

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.

IOKG04 avatar Aug 05 '25 00:08 IOKG04