Zig Version
0.14.0-dev.3223+13ad984b1
Steps to Reproduce and Observed Behavior
const std = @import("std");
pub fn main() !void {
const Key = enum { a };
const Value = union(enum) { x, y };
_ = std.enums.directEnumArray(Key, Value, 0, .{ .a = .x });
}
This fails to compile:
$ zig build
/Users/knut/.local/share/zvm/master/lib/std/enums.zig:124:68: error: expected type 'enums.EnumFieldStruct(main.main.Key,main.main.Value,null)', found 'enums.EnumFieldStruct(main.main.Key,main.main.Value,null)'
return directEnumArrayDefault(E, Data, null, max_unused_slots, init_values);
^~~~~~~~~~~
/Users/knut/.local/share/zvm/master/lib/std/enums.zig:27:12: note: struct declared here (2 times)
return @Type(.{ .@"struct" = .{
^~~~~
/Users/knut/.local/share/zvm/master/lib/std/enums.zig:158:33: note: parameter type declared here
init_values: EnumFieldStruct(E, Data, default),
~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
However, it succeeds in 0.13:
$ zig version
0.13.0
$ zig build && echo "ok"
ok
some investigation
-
Using a tagged union with at least two zero-bit fields is important here. The following values for Value all succeed (without changes to the rest of the example above):
union(enum) { x }
union(enum) { x, y: i32 }
union(enum) { x, y, z: i32 }
union(enum) { x, y: i32, z }
enum { x }
enum { x, y }
-
The following values for Value all fail to compile with the same error, i.e. any zero-bit type triggers the regression:
union(enum) { x: void, y }
union(enum) { x: u0, y }
union(enum) { x: [0]i32, y }
union(enum) { x: [1]u0, y }
union(enum) { x: enum { z }, y }
union(enum) { x: struct {}, y }
union(enum) { x: struct { z: void }, y }
union(enum) { x: union {}, y }
union(enum) { x: union { z: void }, y }
-
Using directEnumArrayDefault directly works, this compiles:
_ = std.enums.directEnumArrayDefault(Key, Value, null, 0, .{ .a = .x });
- Interestingly, using just
directEnumArray afterwards will now work as well, this compiles:
_ = std.enums.directEnumArrayDefault(Key, Value, null, 0, .{ .a = .x });
_ = std.enums.directEnumArray(Key, Value, 0, .{ .a = .x });
but this still doesn't:
_ = std.enums.directEnumArray(Key, Value, 0, .{ .a = .x });
_ = std.enums.directEnumArrayDefault(Key, Value, null, 0, .{ .a = .x });
Expected Behavior
no compilation error
Zig Version
0.14.0-dev.3223+13ad984b1
Steps to Reproduce and Observed Behavior
This fails to compile:
However, it succeeds in 0.13:
some investigation
Using a tagged union with at least two zero-bit fields is important here. The following values for
Valueall succeed (without changes to the rest of the example above):union(enum) { x }union(enum) { x, y: i32 }union(enum) { x, y, z: i32 }union(enum) { x, y: i32, z }enum { x }enum { x, y }The following values for
Valueall fail to compile with the same error, i.e. any zero-bit type triggers the regression:union(enum) { x: void, y }union(enum) { x: u0, y }union(enum) { x: [0]i32, y }union(enum) { x: [1]u0, y }union(enum) { x: enum { z }, y }union(enum) { x: struct {}, y }union(enum) { x: struct { z: void }, y }union(enum) { x: union {}, y }union(enum) { x: union { z: void }, y }Using
directEnumArrayDefaultdirectly works, this compiles:directEnumArrayafterwards will now work as well, this compiles:but this still doesn't:
Expected Behavior
no compilation error