Zig Version
0.16.0
Steps to Reproduce and Observed Behavior
Here's the source file used as proof:
const std = @import("std");
pub const Key = enum(u32){
INVALID = 0x00,
A = 'A',
B = 'B',
C = 'C',
D = 'D',
E = 'E',
F = 'F',
G = 'G',
H = 'H',
I = 'I',
J = 'J',
K = 'K',
L = 'L',
M = 'M',
N = 'N',
O = 'O',
P = 'P',
Q = 'Q',
R = 'R',
S = 'S',
T = 'T',
U = 'U',
V = 'V',
W = 'W',
X = 'X',
Y = 'Y',
Z = 'Z',
@"0" = '0',
@"1" = '1',
@"2" = '2',
@"3" = '3',
@"4" = '4',
@"5" = '5', // 33rd entry - application builds successfully if this is deleted or commented out
};
pub var key_flows: std.enums.EnumArray(Key, u2) = .{.values = @splat(0)};
pub fn main() void {
_ = key_flows; // force analysis
}
And here's the output of zig build-exe used on this source file:
C:\zigtest>zig build-exe enum_proof.zig
C:\zig\lib\std\sort\pdq.zig:22:30: error: evaluation exceeded 1000 backwards branches
return lessThanFn(ctx.sub_ctx, ctx.items[a], ctx.items[b]);
~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\zig\lib\std\sort\pdq.zig:22:30: note: use @setEvalBranchQuota() to raise the branch limit from 1000
C:\zig\lib\std\sort.zig:48:42: note: called at comptime here
while (j > a and context.lessThan(j, j - 1)) : (j -= 1) {
~~~~~~~~~~~~~~~~^~~~~~~~~~
C:\zig\lib\std\sort\pdq.zig:65:44: note: called at comptime here
break sort.insertionContext(range.a, range.b, context);
~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\zig\lib\std\sort\pdq.zig:29:15: note: called at comptime here
pdqContext(0, items.len, Context{ .items = items, .sub_ctx = context });
~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\zig\lib\std\mem.zig:633:17: note: called at comptime here
std.sort.pdq(T, items, context, lessThanFn);
~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\zig\lib\std\enums.zig:1332:25: note: called at comptime here
std.mem.sortUnstable(EnumField, &fields, {}, struct {
~~~~~~~~~~~~~~~~~~~~^
C:\zig\lib\std\enums.zig:1074:40: note: called at comptime here
pub const Indexer = EnumIndexer(E);
~~~~~~~~~~~^~~
referenced by:
enums.EnumArray(enum_proof.Key,u2): C:\zig\lib\std\enums.zig:1082:18
key_flows: enum_proof.zig:39:5
5 reference(s) hidden; use '-freference-trace=7' to see all references
This compile-error also occurs using zig 0.15.2 to compile the same file.
My native target triple is x86_64-windows.win11_dt...win11_dt-gnu, but this error occurs regardless of what target I specify for the compilation.
It also occurs regardless of what optimize mode I specify, and regardless of whether I specify -fno-llvm or -fllvm.
While the application does build successfully if you delete the 33rd field of the enum, it interestingly also builds successfully if you make it so that the values of each field are no longer explicitly specified.
My theory is that the sorting context somehow incurs an extra backwards branch when getting a field's value, only if that field's value is explicitly specified in the enum's definition.
Expected Behavior
Successful program compilation