Zig Version
0.14.0
Steps to Reproduce and Observed Behavior
Hi, it seems that std.MultiArrayList hits the comptime branch quota once the underlying struct gets to 18 or so fields, but I am having some trouble finding the correct placement of @setEvalBranchQuota in client code that will raise the limit.
Here is a repro case that will fail to compile:
const std = @import("std");
const Foo = struct {
a01: u32,
a02: u32,
a03: u32,
a04: u32,
a05: u32,
a06: u32,
a07: u32,
a08: u32,
a09: u32,
a10: u32,
a11: u32,
a12: u32,
a13: u32,
a14: u32,
a15: u32,
a16: u32,
a17: u32,
};
pub fn main() !void {
var gpa: std.heap.DebugAllocator(.{}) = .init;
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var list: std.MultiArrayList(Foo) = .empty;
defer list.deinit(allocator);
try list.resize(allocator, 1);
list.slice().items(.a01)[0] = 42;
}
Here is the output on godbolt for 0.14 (seemingly regardless of where I place @setEvalBranchQuota):
/opt/compiler-explorer/zig-0.14.0/lib/std/math/log2.zig:24:13: error: evaluation exceeded 1000 backwards branches
while (x_shifted >> (shift_amt << 1) != 0) shift_amt <<= 1;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/zig-0.14.0/lib/std/math/log2.zig:24:13: note: use @setEvalBranchQuota() to raise the branch limit from 1000
/opt/compiler-explorer/zig-0.14.0/lib/std/math.zig:779:22: note: called from here
const base = log2(largest_positive_integer);
~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/zig-0.14.0/lib/std/meta.zig:546:49: note: called from here
.tag_type = std.math.IntFittingRange(0, field_infos.len - 1),
~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/zig-0.14.0/lib/std/meta.zig:386:61: note: called from here
pub fn fieldInfo(comptime T: type, comptime field: FieldEnum(T)) switch (@typeInfo(T)) {
~~~~~~~~~^~~
/opt/compiler-explorer/zig-0.14.0/lib/std/multi_array_list.zig:568:34: note: called from here
return meta.fieldInfo(Elem, field).type;
~~~~~~~~~~~~~~^~~~~~~~~~~~~
/opt/compiler-explorer/zig-0.14.0/lib/std/multi_array_list.zig:83:73: note: called from here
pub fn items(self: Slice, comptime field: Field) []FieldType(field) {
~~~~~~~~~^~~~~~~
/opt/compiler-explorer/zig-0.14.0/lib/std/multi_array_list.zig:463:71: note: called from here
@memcpy(other_slice.items(field), self_slice.items(field));
~~~~~~~~~~~~~~~~^~~~~~~
referenced by:
ensureTotalCapacity: /opt/compiler-explorer/zig-0.14.0/lib/std/multi_array_list.zig:411:36
resize: /opt/compiler-explorer/zig-0.14.0/lib/std/multi_array_list.zig:339:41
As a local workaround, I have modified std.MultiArrayList.FieldType to use @FieldType(Elem, @tagName(field)) as its implemention (instead of stuff from std.meta), as this reduces the comptime branch usage a lot and allows this repro case to compile.
However, I am confused how client code could raise the quota for this case so would like to raise it as an issue. I also wonder if std.MultiArrayList or the std.meta functions it relies on are missing some internal @setBranchEvalQuota based on the number of fields of the struct so that it scales to any struct type? (See comments at https://ziggit.dev/t/placement-of-setevalbranchquota/9231/3)
Expected Behavior
It should be possible to use std.MultiArrayList with larger structs without modification to the standard library.
Zig Version
0.14.0
Steps to Reproduce and Observed Behavior
Hi, it seems that
std.MultiArrayListhits the comptime branch quota once the underlying struct gets to 18 or so fields, but I am having some trouble finding the correct placement of@setEvalBranchQuotain client code that will raise the limit.Here is a repro case that will fail to compile:
Here is the output on godbolt for 0.14 (seemingly regardless of where I place
@setEvalBranchQuota):As a local workaround, I have modified
std.MultiArrayList.FieldTypeto use@FieldType(Elem, @tagName(field))as its implemention (instead of stuff fromstd.meta), as this reduces the comptime branch usage a lot and allows this repro case to compile.However, I am confused how client code could raise the quota for this case so would like to raise it as an issue. I also wonder if
std.MultiArrayListor thestd.metafunctions it relies on are missing some internal@setBranchEvalQuotabased on the number of fields of the struct so that it scales to any struct type? (See comments at https://ziggit.dev/t/placement-of-setevalbranchquota/9231/3)Expected Behavior
It should be possible to use
std.MultiArrayListwith larger structs without modification to the standard library.